Convert worker to ESM (#500)
* Convert worker to ESM
To use ESM for the worker, I created a package.json file in worker/ with `{ type: "module" }` as its sole content.
I then rewrote every import to use ESM syntax.
I also tried to set `{ type: "module" }` in the root package.json file to also use ESM in next.config.js.
However, this resulted in a weird problem: default imports were now getting imported as objects in this shape: `{ default: <defaultImport> }`.
Afaik, this should only be the case if you use "import * as foo from 'bar'" syntax: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#default_import
This is fixed by not using `{ type: "module" }` for some reason. However, then, next.config.js also doesn't support ESM import syntax anymore.
The documentation says that if you want to use ESM, you can use next.config.mjs: https://nextjs.org/docs/pages/api-reference/next-config-js
But I didn't want to use MJS extension since I don't have any experience with it. For example, not sure if it's good style to mix JS with MJS etc. So I kept the CJS import syntax there.
* Ignore worker/ during linting
I wasn't able to fix the following errors:
/home/runner/work/stacker.news/stacker.news/worker/auction.js:0:0: Parsing error: No Babel config file detected for /home/runner/work/stacker.news/stacker.news/worker/auction.js. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files. (null)
/home/runner/work/stacker.news/stacker.news/worker/earn.js:0:0: Parsing error: No Babel config file detected for /home/runner/work/stacker.news/stacker.news/worker/earn.js. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files. (null)
/home/runner/work/stacker.news/stacker.news/worker/index.js:0:0: Parsing error: No Babel config file detected for /home/runner/work/stacker.news/stacker.news/worker/index.js. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files. (null)
/home/runner/work/stacker.news/stacker.news/worker/nostr.js:0:0: Parsing error: No Babel config file detected for /home/runner/work/stacker.news/stacker.news/worker/nostr.js. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files. (null)
/home/runner/work/stacker.news/stacker.news/worker/ots.js:0:0: Parsing error: No Babel config file detected for /home/runner/work/stacker.news/stacker.news/worker/ots.js. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files. (null)
/home/runner/work/stacker.news/stacker.news/worker/repin.js:0:0: Parsing error: No Babel config file detected for /home/runner/work/stacker.news/stacker.news/worker/repin.js. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files. (null)
/home/runner/work/stacker.news/stacker.news/worker/search.js:0:0: Parsing error: No Babel config file detected for /home/runner/work/stacker.news/stacker.news/worker/search.js. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files. (null)
/home/runner/work/stacker.news/stacker.news/worker/streak.js:0:0: Parsing error: No Babel config file detected for /home/runner/work/stacker.news/stacker.news/worker/streak.js. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files. (null)
/home/runner/work/stacker.news/stacker.news/worker/trust.js:0:0: Parsing error: No Babel config file detected for /home/runner/work/stacker.news/stacker.news/worker/trust.js. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files. (null)
/home/runner/work/stacker.news/stacker.news/worker/views.js:0:0: Parsing error: No Babel config file detected for /home/runner/work/stacker.news/stacker.news/worker/views.js. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files. (null)
/home/runner/work/stacker.news/stacker.news/worker/wallet.js:0:0: Parsing error: No Babel config file detected for /home/runner/work/stacker.news/stacker.news/worker/wallet.js. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files. (null)
I tried to tell babel where to find the babel config file (.babelrc), specifying the babel config in worker/package.json under "babel", using babel.config.json etc. to no avail.
However, afaict, we don't need babel for the worker since it won't run in a browser. Babel is only used to transpile code to target browsers.
But it still would be nice to lint the worker code with standard.
But we can figure this out later.
* Fix worker imports from lib/ and api/
This fixes the issue that we can't use `{ "type": "module" }` in the root package.json since it breaks the app with this error:
app | TypeError: next_auth_providers_credentials__WEBPACK_IMPORTED_MODULE_2__ is not a function
app | at eval (webpack-internal:///./pages/api/auth/[...nextauth].js:218:20)
app | at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
app | LND GRPC connection successful
app | - error pages/api/auth/[...nextauth].js (139:2) @ CredentialsProvider
app | - error Error [TypeError]: next_auth_providers_credentials__WEBPACK_IMPORTED_MODULE_2__ is not a function
app | at eval (webpack-internal:///./pages/api/auth/[...nextauth].js:218:20) {
app | digest: undefined
app | }
app | 137 |
app | 138 | const providers = [
app | > 139 | CredentialsProvider({
app | | ^
app | 140 | id: 'lightning',
app | 141 | name: 'Lightning',
app | 142 | credentials: {
app | TypeError: next_auth_providers_credentials__WEBPACK_IMPORTED_MODULE_2__ is not a function
app | at eval (webpack-internal:///./pages/api/auth/[...nextauth].js:218:20)
app | at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
build but we need to tell the worker that the files are MJS, else we get this error:
worker | file:///app/worker/wallet.js:3
worker | import { datePivot } from '../lib/time.js'
worker | ^^^^^^^^^
worker | SyntaxError: Named export 'datePivot' not found. The requested module '../lib/time.js' is a CommonJS module, which may not support all module.exports as named exports.
worker | CommonJS modules can always be imported via the default export, for example using:
worker |
worker | import pkg from '../lib/time.js';
worker | const { datePivot } = pkg;
worker |
worker | at ModuleJob._instantiate (node:internal/modules/esm/module_job:124:21)
worker | at async ModuleJob.run (node:internal/modules/esm/module_job:190:5)
worker |
worker | Node.js v18.17.0
worker |
worker exited with code 1
* Fix global not defined in browser context
* Also ignore api/ and lib/ during linting
I did not want to do this but I was not able to fix this error in any other way I tried:
/home/ekzyis/programming/stacker.news/api/lnd/index.js:0:0: Parsing error: No Babel config file detected for /home/ekzyis/programming/stacker.news/api/lnd/index.js. Either disable config file checking with requ
ireConfigFile: false, or configure Babel so that it can find the config files. (null)
Did not want to look deeper into all this standard, eslint, babel configuration stuff ...
---------
Co-authored-by: ekzyis <ek@stacker.news>
Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
2023-09-24 01:19:35 +00:00
|
|
|
import { gql } from 'graphql-tag'
|
|
|
|
import stringifyCanon from 'canonical-json'
|
|
|
|
import { createHash } from 'crypto'
|
|
|
|
import Ots from 'opentimestamps'
|
2023-01-22 20:17:50 +00:00
|
|
|
|
|
|
|
const ITEM_OTS_FIELDS = gql`
|
|
|
|
fragment ItemOTSFields on Item {
|
|
|
|
parentId
|
|
|
|
parentOtsHash
|
|
|
|
title
|
|
|
|
text
|
|
|
|
url
|
|
|
|
}`
|
|
|
|
|
2023-11-21 23:32:22 +00:00
|
|
|
export async function timestampItem ({ data: { id }, apollo, models }) {
|
|
|
|
const { data: { item: { parentId, parentOtsHash, title, text, url } } } = await apollo.query({
|
|
|
|
query: gql`
|
2023-01-22 20:17:50 +00:00
|
|
|
${ITEM_OTS_FIELDS}
|
|
|
|
query Item {
|
|
|
|
item(id: ${id}) {
|
|
|
|
...ItemOTSFields
|
|
|
|
}
|
|
|
|
}`
|
2023-11-21 23:32:22 +00:00
|
|
|
})
|
2023-01-22 20:17:50 +00:00
|
|
|
|
2023-11-21 23:32:22 +00:00
|
|
|
if (parentId && !parentOtsHash) {
|
|
|
|
console.log('no parent hash available ... skipping')
|
|
|
|
return
|
|
|
|
}
|
2023-01-22 20:17:50 +00:00
|
|
|
|
2023-11-21 23:32:22 +00:00
|
|
|
// SHA256 hash item using a canonical serialization format { parentHash, title, text, url }
|
|
|
|
const itemString = stringifyCanon({ parentHash: parentOtsHash, title, text, url })
|
|
|
|
const otsHash = createHash('sha256').update(itemString).digest()
|
|
|
|
const detached = Ots.DetachedTimestampFile.fromHash(new Ots.Ops.OpSHA256(), otsHash)
|
2023-01-22 20:17:50 +00:00
|
|
|
|
2023-11-21 23:32:22 +00:00
|
|
|
// timestamp it
|
|
|
|
await Ots.stamp(detached)
|
2023-01-22 20:17:50 +00:00
|
|
|
|
2023-11-21 23:32:22 +00:00
|
|
|
// get proof
|
|
|
|
const otsFile = Buffer.from(detached.serializeToBytes())
|
2023-01-22 20:17:50 +00:00
|
|
|
|
2023-11-21 23:32:22 +00:00
|
|
|
// store in item
|
|
|
|
await models.item.update({ where: { id }, data: { otsHash: otsHash.toString('hex'), otsFile } })
|
2023-01-22 20:17:50 +00:00
|
|
|
}
|