@typeberry/lib 0.9.0-3f2c45b → 0.9.0-4a9f363

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/package.json +1 -1
  2. package/packages/core/collections/sorted-array.d.ts +1 -1
  3. package/packages/core/collections/sorted-array.d.ts.map +1 -1
  4. package/packages/core/collections/sorted-array.js +4 -2
  5. package/packages/core/collections/sorted-array.test.js +10 -0
  6. package/packages/core/collections/sorted-set.d.ts +1 -1
  7. package/packages/core/collections/sorted-set.d.ts.map +1 -1
  8. package/packages/core/collections/sorted-set.js +6 -2
  9. package/packages/core/collections/sorted-set.test.js +24 -0
  10. package/packages/core/utils/index.d.ts +1 -0
  11. package/packages/core/utils/index.d.ts.map +1 -1
  12. package/packages/core/utils/index.js +1 -0
  13. package/packages/core/utils/shutdown.d.ts +18 -0
  14. package/packages/core/utils/shutdown.d.ts.map +1 -0
  15. package/packages/core/utils/shutdown.js +3 -0
  16. package/packages/core/utils/shutdown.node.d.ts +5 -0
  17. package/packages/core/utils/shutdown.node.d.ts.map +1 -0
  18. package/packages/core/utils/shutdown.node.js +76 -0
  19. package/packages/core/utils/shutdown.test.d.ts +2 -0
  20. package/packages/core/utils/shutdown.test.d.ts.map +1 -0
  21. package/packages/core/utils/shutdown.test.js +164 -0
  22. package/packages/extensions/ipc/server.d.ts.map +1 -1
  23. package/packages/extensions/ipc/server.js +7 -0
  24. package/packages/jam/config-node/node-config.d.ts +20 -2
  25. package/packages/jam/config-node/node-config.d.ts.map +1 -1
  26. package/packages/jam/config-node/node-config.js +25 -3
  27. package/packages/jam/config-node/node-config.test.js +8 -1
  28. package/packages/jam/database/index.d.ts +1 -0
  29. package/packages/jam/database/index.d.ts.map +1 -1
  30. package/packages/jam/database/index.js +1 -0
  31. package/packages/jam/database/leaf-db-update.d.ts +1 -0
  32. package/packages/jam/database/leaf-db-update.d.ts.map +1 -1
  33. package/packages/jam/database/leaf-db-update.js +22 -5
  34. package/packages/jam/database/leaf-db-update.test.d.ts +2 -0
  35. package/packages/jam/database/leaf-db-update.test.d.ts.map +1 -0
  36. package/packages/jam/database/leaf-db-update.test.js +81 -0
  37. package/packages/jam/database/serialized-states-db.d.ts +1 -0
  38. package/packages/jam/database/serialized-states-db.d.ts.map +1 -1
  39. package/packages/jam/database/serialized-states-db.js +4 -0
  40. package/packages/jam/database/states.d.ts +11 -0
  41. package/packages/jam/database/states.d.ts.map +1 -1
  42. package/packages/jam/database/states.js +3 -0
  43. package/packages/jam/database/value-refs.d.ts +117 -0
  44. package/packages/jam/database/value-refs.d.ts.map +1 -0
  45. package/packages/jam/database/value-refs.js +206 -0
  46. package/packages/jam/database/value-refs.test.d.ts +2 -0
  47. package/packages/jam/database/value-refs.test.d.ts.map +1 -0
  48. package/packages/jam/database/value-refs.test.js +165 -0
  49. package/packages/jam/database-fjall/blocks.d.ts +25 -0
  50. package/packages/jam/database-fjall/blocks.d.ts.map +1 -0
  51. package/packages/jam/database-fjall/blocks.js +86 -0
  52. package/packages/jam/database-fjall/blocks.test.d.ts +2 -0
  53. package/packages/jam/database-fjall/blocks.test.d.ts.map +1 -0
  54. package/packages/jam/database-fjall/blocks.test.js +62 -0
  55. package/packages/jam/database-fjall/hybrid-states.d.ts +14 -0
  56. package/packages/jam/database-fjall/hybrid-states.d.ts.map +1 -1
  57. package/packages/jam/database-fjall/hybrid-states.js +55 -6
  58. package/packages/jam/database-fjall/index.d.ts +2 -0
  59. package/packages/jam/database-fjall/index.d.ts.map +1 -1
  60. package/packages/jam/database-fjall/index.js +2 -0
  61. package/packages/jam/database-fjall/root.d.ts +14 -8
  62. package/packages/jam/database-fjall/root.d.ts.map +1 -1
  63. package/packages/jam/database-fjall/root.js +25 -9
  64. package/packages/jam/database-fjall/states.d.ts +31 -0
  65. package/packages/jam/database-fjall/states.d.ts.map +1 -0
  66. package/packages/jam/database-fjall/states.js +99 -0
  67. package/packages/jam/database-fjall/states.test.d.ts +2 -0
  68. package/packages/jam/database-fjall/states.test.d.ts.map +1 -0
  69. package/packages/jam/database-fjall/states.test.js +150 -0
  70. package/packages/jam/database-lmdb/hybrid-states.d.ts +12 -0
  71. package/packages/jam/database-lmdb/hybrid-states.d.ts.map +1 -1
  72. package/packages/jam/database-lmdb/hybrid-states.js +45 -4
  73. package/packages/jam/database-lmdb/states.d.ts +1 -0
  74. package/packages/jam/database-lmdb/states.d.ts.map +1 -1
  75. package/packages/jam/database-lmdb/states.js +5 -0
  76. package/packages/jam/node/export.d.ts.map +1 -1
  77. package/packages/jam/node/export.js +18 -9
  78. package/packages/jam/node/main-fuzz.d.ts +4 -1
  79. package/packages/jam/node/main-fuzz.d.ts.map +1 -1
  80. package/packages/jam/node/main-fuzz.js +111 -82
  81. package/packages/jam/node/main-importer.d.ts +4 -2
  82. package/packages/jam/node/main-importer.d.ts.map +1 -1
  83. package/packages/jam/node/main-importer.js +26 -12
  84. package/packages/jam/node/main.d.ts.map +1 -1
  85. package/packages/jam/node/main.js +42 -15
  86. package/packages/jam/node/workers.d.ts +4 -4
  87. package/packages/jam/node/workers.d.ts.map +1 -1
  88. package/packages/workers/api/config.d.ts +2 -2
  89. package/packages/workers/api/config.d.ts.map +1 -1
  90. package/packages/workers/api/config.js +1 -1
  91. package/packages/workers/api/port.d.ts +5 -1
  92. package/packages/workers/api/port.d.ts.map +1 -1
  93. package/packages/workers/api/port.js +56 -13
  94. package/packages/workers/api/port.test.js +35 -0
  95. package/packages/workers/api-node/config.d.ts +45 -4
  96. package/packages/workers/api-node/config.d.ts.map +1 -1
  97. package/packages/workers/api-node/config.js +127 -9
  98. package/packages/workers/api-node/config.test.js +52 -3
  99. package/packages/workers/api-node/port.d.ts +3 -0
  100. package/packages/workers/api-node/port.d.ts.map +1 -1
  101. package/packages/workers/api-node/port.js +31 -2
  102. package/packages/workers/api-node/port.test.js +17 -0
  103. package/packages/workers/api-node/protocol.d.ts +3 -3
  104. package/packages/workers/api-node/protocol.d.ts.map +1 -1
  105. package/packages/workers/api-node/protocol.js +18 -12
  106. package/packages/workers/block-authorship/main.js +1 -1
  107. package/packages/workers/importer/main.d.ts +1 -1
  108. package/packages/workers/importer/main.d.ts.map +1 -1
  109. package/packages/workers/importer/main.js +1 -1
  110. package/packages/workers/jam-network/main.js +1 -1
@@ -75,6 +75,10 @@ export async function mainFuzz(fuzzConfig, withRelPath) {
75
75
  // every reset, because opening it is the slow part. Only the in-memory blocks
76
76
  // and leaf sets are rebuilt for each vector. fjall-hybrid only.
77
77
  let fjallSession = null;
78
+ // Set when close() starts. Guards resetState so a fuzz command arriving
79
+ // mid-shutdown can't build a fresh node that close() then orphans.
80
+ let isClosing = false;
81
+ let activeReset = null;
78
82
  const chainSpec = getChainSpec(config.node.flavor);
79
83
  const closeFuzzTarget = startFuzzTarget(fuzzConfig.version, fuzzConfig.socket, {
80
84
  ...getFuzzDetails(),
@@ -98,97 +102,122 @@ export async function mainFuzz(fuzzConfig, withRelPath) {
98
102
  }
99
103
  return runningNode.getStateEntries(hash);
100
104
  },
101
- resetState: async (header, state, ancestry) => {
102
- if (runningNode !== null) {
103
- const finish = runningNode.close();
104
- runningNode = null;
105
- await finish;
106
- }
107
- const buildNode = (databaseBasePath) => {
108
- const isPersistent = databaseBasePath !== undefined;
109
- return mainImporter({
110
- ...config,
111
- node: {
112
- ...config.node,
113
- databaseBasePath,
114
- chainSpec: {
115
- ...config.node.chainSpec,
116
- genesisHeader: Encoder.encodeObject(Header.Codec, header, chainSpec),
117
- genesisState: new Map(state),
105
+ resetState: (header, state, ancestry) => {
106
+ const reset = (async () => {
107
+ if (isClosing) {
108
+ return Bytes.zero(HASH_SIZE).asOpaque();
109
+ }
110
+ if (runningNode !== null) {
111
+ const finish = runningNode.close();
112
+ runningNode = null;
113
+ await finish;
114
+ }
115
+ const buildNode = (databaseBasePath) => {
116
+ const isPersistent = databaseBasePath !== undefined;
117
+ return mainImporter({
118
+ ...config,
119
+ node: {
120
+ ...config.node,
121
+ databaseBasePath,
122
+ chainSpec: {
123
+ ...config.node.chainSpec,
124
+ genesisHeader: Encoder.encodeObject(Header.Codec, header, chainSpec),
125
+ genesisState: new Map(state),
126
+ },
118
127
  },
119
- },
120
- ancestry,
121
- network: null,
122
- }, withRelPath, {
123
- initGenesisFromAncestry: fuzzConfig.initGenesisFromAncestry,
124
- // Hybrid keeps leaf sets in RAM, so they must be windowed exactly
125
- // like the in-memory backend; only the large values live on disk.
126
- dummyFinalityDepth: 20,
127
- pruneBlocks: true,
128
- // The on-disk fuzz db is throwaway (we wipe it), so open it ephemeral and
129
- // skip the fsync, we do not need durability here. On full spec ephemeral
130
- // also turns on compression further down, so the big values do not grow the
131
- // db too much. Tiny stays uncompressed, its db is small and speed matters more.
132
- ephemeral: isPersistent,
133
- stateBackend: isPersistent ? hybridStateBackend : "lmdb",
134
- // Reuse the session keyspace (fjall-hybrid only, other backends
135
- // ignore it). Nothing to pass for the in-memory fallback.
136
- sharedFjallSession: isPersistent ? (fjallSession ?? undefined) : undefined,
137
- });
138
- };
139
- if (fuzzDbBase !== undefined) {
140
- try {
141
- if (hybridStateBackend === FUZZ_DB_FJALL) {
142
- // fjall-hybrid: open the values keyspace once and reuse it on every
143
- // reset. The values partition is content-addressed and immutable, so
144
- // it is fine that values pile up across resets, the unreferenced ones
145
- // just sit there. `initializeDatabase` decides whether the db is
146
- // already initialized from the in-memory blocks, which we rebuild on
147
- // every reset, not from the values store, so reusing it does not
148
- // resume the previous run.
149
- if (fjallSession === null) {
150
- // Start from a clean slate once, then keep the keyspace open.
128
+ ancestry,
129
+ network: null,
130
+ }, withRelPath, {
131
+ initGenesisFromAncestry: fuzzConfig.initGenesisFromAncestry,
132
+ // Hybrid keeps leaf sets in RAM, so they must be windowed exactly
133
+ // like the in-memory backend; only the large values live on disk.
134
+ dummyFinalityDepth: 20,
135
+ pruneBlocks: true,
136
+ // The on-disk fuzz db is throwaway (we wipe it), so open it ephemeral and
137
+ // skip the fsync, we do not need durability here. On full spec ephemeral
138
+ // also turns on compression further down, so the big values do not grow the
139
+ // db too much. Tiny stays uncompressed, its db is small and speed matters more.
140
+ ephemeral: isPersistent,
141
+ stateBackend: isPersistent ? hybridStateBackend : "lmdb",
142
+ // Reuse the session keyspace (fjall-hybrid only, other backends
143
+ // ignore it). Nothing to pass for the in-memory fallback.
144
+ sharedFjallSession: isPersistent ? (fjallSession ?? undefined) : undefined,
145
+ });
146
+ };
147
+ if (fuzzDbBase !== undefined) {
148
+ try {
149
+ if (hybridStateBackend === FUZZ_DB_FJALL) {
150
+ // fjall-hybrid: open the values keyspace once and reuse it on every
151
+ // reset. The values partition is content-addressed and immutable, so
152
+ // it is fine that values pile up across resets, the unreferenced ones
153
+ // just sit there. `initializeDatabase` decides whether the db is
154
+ // already initialized from the in-memory blocks, which we rebuild on
155
+ // every reset, not from the values store, so reusing it does not
156
+ // resume the previous run.
157
+ if (fjallSession === null) {
158
+ // Start from a clean slate once, then keep the keyspace open.
159
+ await wipeFuzzDb(fuzzDbBase);
160
+ fjallSession = await FjallValuesSession.open(`${withRelPath(fuzzDbBase)}/${FUZZ_FJALL_VALUES_SUBDIR}`, {
161
+ ephemeral: true,
162
+ cacheSizeBytes: FUZZ_FJALL_CACHE_BYTES,
163
+ });
164
+ logger.info `🗄️ Opened reusable fjall values session at ${withRelPath(fuzzDbBase)}/${FUZZ_FJALL_VALUES_SUBDIR}`;
165
+ }
166
+ }
167
+ else {
168
+ // lmdb-hybrid: keep the old behaviour, wipe and reopen on every
169
+ // reset. A fresh db each reset makes `initializeDatabase` set up
170
+ // genesis again instead of resuming the previous run.
151
171
  await wipeFuzzDb(fuzzDbBase);
152
- fjallSession = await FjallValuesSession.open(`${withRelPath(fuzzDbBase)}/${FUZZ_FJALL_VALUES_SUBDIR}`, {
153
- ephemeral: true,
154
- cacheSizeBytes: FUZZ_FJALL_CACHE_BYTES,
155
- });
156
- logger.info `🗄️ Opened reusable fjall values session at ${withRelPath(fuzzDbBase)}/${FUZZ_FJALL_VALUES_SUBDIR}`;
157
172
  }
173
+ runningNode = await buildNode(fuzzDbBase);
174
+ return await runningNode.getBestStateRootHash();
158
175
  }
159
- else {
160
- // lmdb-hybrid: keep the old behaviour, wipe and reopen on every
161
- // reset. A fresh db each reset makes `initializeDatabase` set up
162
- // genesis again instead of resuming the previous run.
163
- await wipeFuzzDb(fuzzDbBase);
176
+ catch (e) {
177
+ // A partially-opened db may leak on failure; acceptable for this degraded fallback (proper cleanup belongs in mainImporter).
178
+ logger.warn `Failed to open persistent fuzz db at ${fuzzDbBase}, falling back to in-memory: ${e}`;
179
+ runningNode = null;
164
180
  }
165
- runningNode = await buildNode(fuzzDbBase);
166
- return await runningNode.getBestStateRootHash();
167
181
  }
168
- catch (e) {
169
- // A partially-opened db may leak on failure; acceptable for this degraded fallback (proper cleanup belongs in mainImporter).
170
- logger.warn `Failed to open persistent fuzz db at ${fuzzDbBase}, falling back to in-memory: ${e}`;
171
- runningNode = null;
182
+ runningNode = await buildNode(undefined);
183
+ return await runningNode.getBestStateRootHash();
184
+ })();
185
+ activeReset = reset;
186
+ const clearActiveReset = () => {
187
+ if (activeReset === reset) {
188
+ activeReset = null;
172
189
  }
173
- }
174
- runningNode = await buildNode(undefined);
175
- return await runningNode.getBestStateRootHash();
190
+ };
191
+ reset.then(clearActiveReset, clearActiveReset);
192
+ return reset;
176
193
  },
177
194
  });
178
- return () => {
179
- closeFuzzTarget();
180
- // Close the reused fjall values session (if any) before wiping its files, so
181
- // the keyspace handle is released first.
182
- const closed = fjallSession?.close() ?? Promise.resolve();
183
- fjallSession = null;
184
- if (fuzzDbBase !== undefined) {
185
- // best-effort cleanup on shutdown; ignore failures (dir may already be gone).
186
- closed
187
- .catch(() => { })
188
- .finally(() => {
189
- wipeFuzzDb(fuzzDbBase).catch(() => { });
190
- });
191
- }
195
+ return {
196
+ close: async () => {
197
+ isClosing = true;
198
+ // Stop accepting connections + unlink the socket.
199
+ closeFuzzTarget();
200
+ // Drain the active session (flush + close DB). Swallow errors so a
201
+ // failing close still lets the process exit 0; the db is wiped next.
202
+ // The node references the shared fjall session, so it must close first.
203
+ if (activeReset !== null) {
204
+ await activeReset.catch((e) => logger.error `Error waiting for fuzz reset: ${e}`);
205
+ }
206
+ if (runningNode !== null) {
207
+ const node = runningNode;
208
+ runningNode = null;
209
+ await node.close().catch((e) => logger.error `Error closing fuzz node: ${e}`);
210
+ }
211
+ // Release the reused fjall values keyspace before wiping its files.
212
+ if (fjallSession !== null) {
213
+ const session = fjallSession;
214
+ fjallSession = null;
215
+ await session.close().catch((e) => logger.error `Error closing fjall session: ${e}`);
216
+ }
217
+ if (fuzzDbBase !== undefined) {
218
+ await wipeFuzzDb(fuzzDbBase).catch(() => { });
219
+ }
220
+ },
192
221
  };
193
222
  }
194
223
  function isValidStateBackend(val) {
@@ -1,7 +1,7 @@
1
1
  import { type FjallValuesSession } from "#@typeberry/workers-api-node";
2
2
  import type { JamConfig } from "./jam-config.js";
3
3
  import type { NodeApi } from "./main.js";
4
- export type StateBackend = "lmdb" | "lmdb-hybrid" | "fjall-hybrid";
4
+ export type StateBackend = "lmdb" | "fjall" | "lmdb-hybrid" | "fjall-hybrid";
5
5
  export type ImporterOptions = {
6
6
  initGenesisFromAncestry?: boolean;
7
7
  dummyFinalityDepth?: number;
@@ -9,7 +9,9 @@ export type ImporterOptions = {
9
9
  /** Open the database without fsync/compression. Only safe for throwaway dbs (e.g. fuzzing). */
10
10
  ephemeral?: boolean;
11
11
  /**
12
- * Persistent backend used when `databaseBasePath` is set. Defaults to full LMDB.
12
+ * Persistent backend used when `databaseBasePath` is set. Defaults to config's backend (fjall unless overridden).
13
+ *
14
+ * lmdb and lmdb-hybrid are deprecated and retained as explicit fallbacks.
13
15
  */
14
16
  stateBackend?: StateBackend;
15
17
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"main-importer.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/main-importer.ts"],"names":[],"mappings":"AASA,OAAO,EACL,KAAK,kBAAkB,EAIxB,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,aAAa,GAAG,cAAc,CAAC;AAEnE,MAAM,MAAM,eAAe,GAAG;IAC5B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+FAA+F;IAC/F,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC,CAAC;AAEF,wBAAsB,YAAY,CAChC,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAClC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,OAAO,CAAC,CAsGlB"}
1
+ {"version":3,"file":"main-importer.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/main-importer.ts"],"names":[],"mappings":"AASA,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,GAAG,cAAc,CAAC;AAE7E,MAAM,MAAM,eAAe,GAAG;IAC5B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+FAA+F;IAC/F,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC,CAAC;AAEF,wBAAsB,YAAY,CAChC,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAClC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,OAAO,CAAC,CAqHlB"}
@@ -1,12 +1,12 @@
1
1
  import { Bytes } from "#@typeberry/bytes";
2
2
  import { PvmBackend } from "#@typeberry/config";
3
- import { KnownChainSpec } from "#@typeberry/config-node";
3
+ import { KnownChainSpec, RegularStateBackend } from "#@typeberry/config-node";
4
4
  import { bandersnatch, initWasm } from "#@typeberry/crypto";
5
5
  import { Blake2b, HASH_SIZE } from "#@typeberry/hash";
6
6
  import { createImporter, ImporterConfig } from "#@typeberry/importer";
7
7
  import { tryAsU16 } from "#@typeberry/numbers";
8
8
  import { CURRENT_SUITE, CURRENT_VERSION, Result, resultToString, version } from "#@typeberry/utils";
9
- import { HybridWorkerConfig, InMemWorkerConfig, LmdbWorkerConfig, } from "#@typeberry/workers-api-node";
9
+ import { FjallWorkerConfig, HybridWorkerConfig, InMemWorkerConfig, LmdbWorkerConfig, } from "#@typeberry/workers-api-node";
10
10
  import { getChainSpec, getDatabasePath, initializeDatabase, logger } from "./common.js";
11
11
  const zeroHash = Bytes.zero(HASH_SIZE).asOpaque();
12
12
  export async function mainImporter(config, withRelPath, options = {}) {
@@ -18,8 +18,13 @@ export async function mainImporter(config, withRelPath, options = {}) {
18
18
  logger.info `🐇 Bandersnatch ${bandesnatchNative.isOk ? "native 🚀" : `using wasm: ${bandesnatchNative.error}`}`;
19
19
  // Single source of truth for the states db backend: drives both the log line
20
20
  // below and the worker config picked further down.
21
- const dbBackend = config.node.databaseBasePath === undefined ? "in-memory" : (options.stateBackend ?? "lmdb");
21
+ const dbBackend = config.node.databaseBasePath === undefined
22
+ ? "in-memory"
23
+ : (options.stateBackend ?? config.node.stateBackend ?? RegularStateBackend.Fjall);
22
24
  logger.info `🗄️ States DB: ${dbBackend}.`;
25
+ if (dbBackend === "lmdb" || dbBackend === "lmdb-hybrid") {
26
+ logger.warn `🗄️ The ${dbBackend} state backend is deprecated. Use fjall unless you need a temporary fallback.`;
27
+ }
23
28
  const chainSpec = getChainSpec(config.node.flavor);
24
29
  const blake2b = await Blake2b.createHasher();
25
30
  const nodeName = config.nodeName;
@@ -51,17 +56,26 @@ export async function mainImporter(config, withRelPath, options = {}) {
51
56
  backend: dbBackend === "lmdb-hybrid" ? "lmdb" : "fjall",
52
57
  sharedFjallSession: options.sharedFjallSession,
53
58
  })
54
- : LmdbWorkerConfig.new({
55
- nodeName,
56
- chainSpec,
57
- blake2b,
58
- dbPath,
59
- workerParams,
60
- ephemeral,
61
- });
59
+ : dbBackend === "fjall"
60
+ ? FjallWorkerConfig.new({
61
+ nodeName,
62
+ chainSpec,
63
+ blake2b,
64
+ dbPath,
65
+ workerParams,
66
+ ephemeral,
67
+ })
68
+ : LmdbWorkerConfig.new({
69
+ nodeName,
70
+ chainSpec,
71
+ blake2b,
72
+ dbPath,
73
+ workerParams,
74
+ ephemeral,
75
+ });
62
76
  // Initialize the database with genesis state and block if there isn't one.
63
77
  logger.info `🛢️ Opening database at ${dbPath}`;
64
- const rootDb = workerConfig.openDatabase({ readonly: false });
78
+ const rootDb = await workerConfig.openDatabase({ readonly: false });
65
79
  await initializeDatabase(chainSpec, blake2b, genesisHeaderHash, rootDb, config.node.chainSpec, config.ancestry, {
66
80
  initGenesisFromAncestry: options.initGenesisFromAncestry,
67
81
  });
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/main.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAc,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEzF,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,mBAAmB,CAAC;AAe/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAkC,MAAM,EAAW,MAAM,kBAAkB,CAAC;AAKnF,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,iBAAiB,CAAC;AAWhE,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAChE,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;IACtE,oBAAoB,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAC/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF,wBAAsB,IAAI,CACxB,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAClC,SAAS,EAAE,SAAS,GAAG,IAAI,GAC1B,OAAO,CAAC,OAAO,CAAC,CA2KlB"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/main.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAc,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEzF,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,mBAAmB,CAAC;AAgB/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAkC,MAAM,EAAW,MAAM,kBAAkB,CAAC;AAYnF,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,iBAAiB,CAAC;AAWhE,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAChE,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;IACtE,oBAAoB,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAC/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF,wBAAsB,IAAI,CACxB,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAClC,SAAS,EAAE,SAAS,GAAG,IAAI,GAC1B,OAAO,CAAC,OAAO,CAAC,CA2LlB"}
@@ -1,6 +1,7 @@
1
1
  import { isMainThread } from "node:worker_threads";
2
2
  import { AUTHORSHIP_NETWORK_PORT } from "#@typeberry/comms-authorship-network";
3
3
  import { PvmBackend } from "#@typeberry/config";
4
+ import { RegularStateBackend } from "#@typeberry/config-node";
4
5
  import { initWasm } from "#@typeberry/crypto";
5
6
  import { deriveBandersnatchSecretKey, deriveEd25519SecretKey, trivialSeed, } from "#@typeberry/crypto/key-derivation.js";
6
7
  import { Blake2b } from "#@typeberry/hash";
@@ -10,7 +11,7 @@ import { Listener } from "#@typeberry/listener";
10
11
  import { tryAsU16, tryAsU32 } from "#@typeberry/numbers";
11
12
  import { CURRENT_SUITE, CURRENT_VERSION, Result, version } from "#@typeberry/utils";
12
13
  import { DirectPort, DirectWorkerConfig } from "#@typeberry/workers-api";
13
- import { InMemWorkerConfig, LmdbWorkerConfig, logHostEnvironment, ThreadPort } from "#@typeberry/workers-api-node";
14
+ import { FjallWorkerConfig, InMemWorkerConfig, LmdbWorkerConfig, logHostEnvironment, ThreadPort, } from "#@typeberry/workers-api-node";
14
15
  import { getChainSpec, getDatabasePath, initializeDatabase, logger } from "./common.js";
15
16
  import { initializeExtensions } from "./extensions.js";
16
17
  import * as metrics from "./metrics.js";
@@ -29,9 +30,12 @@ export async function main(config, withRelPath, telemetry) {
29
30
  const blake2b = await Blake2b.createHasher();
30
31
  const nodeName = config.nodeName;
31
32
  const isInMemory = config.node.databaseBasePath === undefined;
32
- logger.info `🗄️ States DB: ${isInMemory ? "in-memory" : "lmdb"}.`;
33
+ logger.info `🗄️ States DB: ${isInMemory ? "in-memory" : config.node.stateBackend}.`;
34
+ if (!isInMemory && config.node.stateBackend === RegularStateBackend.Lmdb) {
35
+ logger.warn `🗄️ The lmdb state backend is deprecated. Use state_backend="fjall" unless you need a temporary fallback.`;
36
+ }
33
37
  const { dbPath, genesisHeaderHash } = getDatabasePath(blake2b, nodeName, config.node.chainSpec.genesisHeader, withRelPath(config.node.databaseBasePath ?? "<in-memory>"));
34
- const baseConfig = { nodeName, chainSpec, blake2b, dbPath };
38
+ const baseConfig = { nodeName, chainSpec, blake2b, dbPath, stateBackend: config.node.stateBackend };
35
39
  const importerParams = {
36
40
  ...baseConfig,
37
41
  workerParams: ImporterConfig.create({
@@ -42,16 +46,29 @@ export async function main(config, withRelPath, telemetry) {
42
46
  };
43
47
  const importerConfig = isInMemory
44
48
  ? { isInMemory, config: InMemWorkerConfig.new(importerParams) }
45
- : { isInMemory, config: LmdbWorkerConfig.new(importerParams) };
49
+ : { isInMemory, config: createPersistentWorkerConfig(importerParams) };
46
50
  // Initialize the database with genesis state and block if there isn't one.
47
51
  logger.info `🛢️ Opening database at ${dbPath}`;
48
- const rootDb = importerConfig.config.openDatabase({ readonly: false });
49
- await initializeDatabase(chainSpec, blake2b, genesisHeaderHash, rootDb, config.node.chainSpec, config.ancestry);
50
- // NOTE [ToDr] even though, we should be closing the database here,
51
- // it seems that opening it in the main thread for writing, and later
52
- // in the importer thread, causes issues. Everything works fine though,
53
- // if we DO NOT close the database (I guess it's process-shared?)
54
- // await rootDb.close();
52
+ const rootDb = await importerConfig.config.openDatabase({ readonly: false });
53
+ try {
54
+ await initializeDatabase(chainSpec, blake2b, genesisHeaderHash, rootDb, config.node.chainSpec, config.ancestry);
55
+ }
56
+ catch (e) {
57
+ try {
58
+ await rootDb.close();
59
+ }
60
+ catch (closeError) {
61
+ logger.warn `Failed to close database after initialization error: ${closeError}`;
62
+ }
63
+ throw e;
64
+ }
65
+ // fjall-js shares the engine explicitly and requires every handle to close.
66
+ // Keep lmdb's historical main-thread handle open until shutdown.
67
+ let mainRootDb = rootDb;
68
+ if (!importerConfig.isInMemory && config.node.stateBackend === RegularStateBackend.Fjall) {
69
+ await rootDb.close();
70
+ mainRootDb = null;
71
+ }
55
72
  // Start block importer
56
73
  let importer;
57
74
  let closeImporter;
@@ -138,8 +155,10 @@ export async function main(config, withRelPath, telemetry) {
138
155
  await closeImporter();
139
156
  logger.log `[main] ☠️ Closing the extensions`;
140
157
  closeExtensions();
141
- logger.log `[main] 🛢️ Closing the database`;
142
- await rootDb.close();
158
+ if (mainRootDb !== null) {
159
+ logger.log `[main] 🛢️ Closing the database`;
160
+ await mainRootDb.close();
161
+ }
143
162
  logger.log `[main] 📳 Closing telemetry`;
144
163
  await telemetry?.close();
145
164
  logger.info `[main] ✅ Done.`;
@@ -167,7 +186,7 @@ const initAuthorship = async (importer, isAuthoring, isFastForward, params, base
167
186
  statesDb: params.rootDb.getStatesDb(),
168
187
  workerParams,
169
188
  }), params.networkingPort)
170
- : await spawnBlockGeneratorWorker(LmdbWorkerConfig.new({
189
+ : await spawnBlockGeneratorWorker(createPersistentWorkerConfig({
171
190
  ...baseConfig,
172
191
  workerParams,
173
192
  ports: new Map([[AUTHORSHIP_NETWORK_PORT, params.networkingPort]]),
@@ -205,7 +224,7 @@ const initNetwork = async (importer, params, baseConfig, genesisHeaderHash, netw
205
224
  statesDb: params.rootDb.getStatesDb(),
206
225
  workerParams: networkingConfig,
207
226
  }), params.authorshipPort)
208
- : await spawnNetworkWorker(LmdbWorkerConfig.new({
227
+ : await spawnNetworkWorker(createPersistentWorkerConfig({
209
228
  ...baseConfig,
210
229
  workerParams: networkingConfig,
211
230
  ports: new Map([[AUTHORSHIP_NETWORK_PORT, params.authorshipPort]]),
@@ -222,3 +241,11 @@ const initNetwork = async (importer, params, baseConfig, genesisHeaderHash, netw
222
241
  });
223
242
  return { closeNetwork: finish, networkApi: network, networkWorker: worker };
224
243
  };
244
+ function createPersistentWorkerConfig({ stateBackend, ...params }) {
245
+ switch (stateBackend) {
246
+ case RegularStateBackend.Fjall:
247
+ return FjallWorkerConfig.new(params);
248
+ case RegularStateBackend.Lmdb:
249
+ return LmdbWorkerConfig.new(params);
250
+ }
251
+ }
@@ -5,8 +5,8 @@ import * as importer from "#@typeberry/importer";
5
5
  import * as jamNetwork from "#@typeberry/jam-network";
6
6
  import type { SerializedState } from "#@typeberry/state-merkleization";
7
7
  import { type DirectPort, type DirectWorkerConfig } from "#@typeberry/workers-api";
8
- import { type LmdbWorkerConfig } from "#@typeberry/workers-api-node";
9
- export declare function spawnImporterWorker(config: LmdbWorkerConfig<importer.ImporterConfig>): Promise<{
8
+ import { type PersistentWorkerConfig } from "#@typeberry/workers-api-node";
9
+ export declare function spawnImporterWorker(config: PersistentWorkerConfig<importer.ImporterConfig>): Promise<{
10
10
  importer: import("@typeberry/workers-api").Tx<{
11
11
  getStateEntries: {
12
12
  request: import("@typeberry/codec").Descriptor<import("@typeberry/bytes").Bytes<32> & import("@typeberry/utils").WithOpaque<"HeaderHash">, import("@typeberry/bytes").Bytes<32>>;
@@ -376,7 +376,7 @@ export declare function spawnImporterWorker(config: LmdbWorkerConfig<importer.Im
376
376
  finish: () => Promise<void>;
377
377
  }>;
378
378
  export declare function startImporterDirect(config: DirectWorkerConfig<importer.ImporterConfig, BlocksDb, StatesDb<SerializedState<LeafDb>>>): ReturnType<typeof spawnImporterWorker>;
379
- export declare function spawnNetworkWorker(config: LmdbWorkerConfig<jamNetwork.NetworkingConfig>): Promise<{
379
+ export declare function spawnNetworkWorker(config: PersistentWorkerConfig<jamNetwork.NetworkingConfig>): Promise<{
380
380
  network: import("@typeberry/workers-api").Tx<{
381
381
  newHeader: {
382
382
  request: import("@typeberry/codec").Descriptor<import("@typeberry/hash").WithHash<import("@typeberry/hash").OpaqueHash & import("@typeberry/utils").WithOpaque<"HeaderHash">, import("@typeberry/codec").ViewOf<import("@typeberry/block").Header & import("@typeberry/codec").CodecRecord<import("@typeberry/block").Header>, {
@@ -865,7 +865,7 @@ export declare function spawnNetworkWorker(config: LmdbWorkerConfig<jamNetwork.N
865
865
  export declare function startNetwork(config: DirectWorkerConfig<jamNetwork.NetworkingConfig>, authorshipPort: DirectPort): Promise<Omit<Awaited<ReturnType<typeof spawnNetworkWorker>>, "worker"> & {
866
866
  worker: Worker | null;
867
867
  }>;
868
- export declare function spawnBlockGeneratorWorker(config: LmdbWorkerConfig<blockAuthorship.BlockAuthorshipConfig>): Promise<{
868
+ export declare function spawnBlockGeneratorWorker(config: PersistentWorkerConfig<blockAuthorship.BlockAuthorshipConfig>): Promise<{
869
869
  generator: import("@typeberry/workers-api").Tx<{
870
870
  finish: {
871
871
  request: import("@typeberry/codec").Descriptor<void, void>;
@@ -1 +1 @@
1
- {"version":3,"file":"workers.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/workers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,eAAe,MAAM,6BAA6B,CAAC;AAE/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAW,KAAK,UAAU,EAAE,KAAK,kBAAkB,EAAmB,MAAM,wBAAwB,CAAC;AAC5G,OAAO,EAAE,KAAK,gBAAgB,EAAe,MAAM,6BAA6B,CAAC;AAEjF,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,cAAc,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgB1F;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,kBAAkB,CAAC,QAAQ,CAAC,cAAc,EAAE,QAAQ,EAAE,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,GAC/F,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAaxC;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,CAAC,UAAU,CAAC,gBAAgB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiB7F;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,kBAAkB,CAAC,UAAU,CAAC,gBAAgB,CAAC,EACvD,cAAc,EAAE,UAAU,GACzB,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAerG;AAED,wBAAsB,yBAAyB,CAAC,MAAM,EAAE,gBAAgB,CAAC,eAAe,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiB9G;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,kBAAkB,CAAC,eAAe,CAAC,qBAAqB,CAAC,EACjE,cAAc,EAAE,UAAU,GACzB,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAgB5G"}
1
+ {"version":3,"file":"workers.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/workers.ts"],"names":[],"mappings":"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"}
@@ -11,7 +11,7 @@ export interface WorkerConfig<TParams = void, TBlocks = BlocksDb, TStates = Stat
11
11
  /** Open database. */
12
12
  openDatabase(options?: {
13
13
  readonly: boolean;
14
- }): RootDb<TBlocks, TStates>;
14
+ }): Promise<RootDb<TBlocks, TStates>>;
15
15
  }
16
16
  /**
17
17
  * Worker config with in-thread database.
@@ -32,6 +32,6 @@ export declare class DirectWorkerConfig<TParams = void, TBlocks = BlocksDb, TSta
32
32
  private constructor();
33
33
  openDatabase(_options?: {
34
34
  readonly: boolean;
35
- }): RootDb<TBlocks, TStates>;
35
+ }): Promise<RootDb<TBlocks, TStates>>;
36
36
  }
37
37
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEtE,kCAAkC;AAClC,MAAM,WAAW,YAAY,CAAC,OAAO,GAAG,IAAI,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,GAAG,QAAQ;IAClF,iBAAiB;IACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,kBAAkB;IAClB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,yBAAyB;IACzB,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAE/B,qBAAqB;IACrB,YAAY,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,GAAG,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;CACzE;AAED;;GAEG;AACH,qBAAa,kBAAkB,CAAC,OAAO,GAAG,IAAI,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,GAAG,QAAQ,CACpF,YAAW,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;aAmBhC,QAAQ,EAAE,MAAM;aAChB,SAAS,EAAE,SAAS;aACpB,YAAY,EAAE,OAAO;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IArB3B,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAClB,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,YAAY,EAAE,MAAM,GACrB,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,SAAS,CAAC;QACrB,QAAQ,EAAE,CAAC,CAAC;QACZ,QAAQ,EAAE,CAAC,CAAC;QACZ,YAAY,EAAE,CAAC,CAAC;KACjB,GAAG,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAI/B,OAAO;IAQP,YAAY,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,GAAG,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;CAOzE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEtE,kCAAkC;AAClC,MAAM,WAAW,YAAY,CAAC,OAAO,GAAG,IAAI,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,GAAG,QAAQ;IAClF,iBAAiB;IACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,kBAAkB;IAClB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,yBAAyB;IACzB,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAE/B,qBAAqB;IACrB,YAAY,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;CAClF;AAED;;GAEG;AACH,qBAAa,kBAAkB,CAAC,OAAO,GAAG,IAAI,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,GAAG,QAAQ,CACpF,YAAW,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;aAmBhC,QAAQ,EAAE,MAAM;aAChB,SAAS,EAAE,SAAS;aACpB,YAAY,EAAE,OAAO;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IArB3B,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAClB,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,YAAY,EAAE,MAAM,GACrB,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,SAAS,CAAC;QACrB,QAAQ,EAAE,CAAC,CAAC;QACZ,QAAQ,EAAE,CAAC,CAAC;QACZ,YAAY,EAAE,CAAC,CAAC;KACjB,GAAG,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAI/B,OAAO;IAQD,YAAY,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;CAOxF"}
@@ -17,7 +17,7 @@ export class DirectWorkerConfig {
17
17
  this.blocksDb = blocksDb;
18
18
  this.statesDb = statesDb;
19
19
  }
20
- openDatabase(_options) {
20
+ async openDatabase(_options) {
21
21
  return {
22
22
  getBlocksDb: () => this.blocksDb,
23
23
  getStatesDb: () => this.statesDb,
@@ -44,7 +44,8 @@ export interface Port {
44
44
  * so there is no need for any serialization - we simply pass the data.
45
45
  */
46
46
  export declare class DirectPort implements Port {
47
- private readonly events;
47
+ private readonly inbound;
48
+ private readonly outbound;
48
49
  readonly threadId = 0;
49
50
  /** Create a pair of symmetrical inter-connected ports. */
50
51
  static pair(): [DirectPort, DirectPort];
@@ -54,5 +55,8 @@ export declare class DirectPort implements Port {
54
55
  once<T>(event: string, _codec: Codec<T>, callback: (msg: Envelope<T>) => void): () => void;
55
56
  postMessage<T>(event: string, _codec: Codec<T>, msg: Envelope<T>): void;
56
57
  close(): void;
58
+ private queuePending;
59
+ private flushPending;
60
+ private closeState;
57
61
  }
58
62
  //# sourceMappingURL=port.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"port.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api/port.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAG9C;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,CAAC,CAAC;CACT,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,IAAI;IACnB,0BAA0B;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,0FAA0F;IAC1F,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IAE5C;;;;OAIG;IACH,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAExF;;;;OAIG;IACH,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAE1F,2EAA2E;IAC3E,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAEvE,yCAAyC;IACzC,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;;;;GAKG;AACH,qBAAa,UAAW,YAAW,IAAI;IASjB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAR3C,QAAQ,CAAC,QAAQ,KAAK;IAEtB,0DAA0D;IAC1D,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC;IAKvC,OAAO;IAEP,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAI3C,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI;IAYxF,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI;IAY1F,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI;IAIvE,KAAK;CAIN"}
1
+ {"version":3,"file":"port.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api/port.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAG9C;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,CAAC,CAAC;CACT,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,IAAI;IACnB,0BAA0B;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,0FAA0F;IAC1F,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IAE5C;;;;OAIG;IACH,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAExF;;;;OAIG;IACH,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAE1F,2EAA2E;IAC3E,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAEvE,yCAAyC;IACzC,KAAK,IAAI,IAAI,CAAC;CACf;AAOD;;;;;GAKG;AACH,qBAAa,UAAW,YAAW,IAAI;IAWnC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAX3B,QAAQ,CAAC,QAAQ,KAAK;IAEtB,0DAA0D;IAC1D,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC;IAMvC,OAAO;IAKP,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAI3C,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI;IAaxF,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI;IAuB1F,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI;IAQvE,KAAK;IAKL,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,UAAU;CAKnB"}