@topgunbuild/server 0.10.0 → 0.10.1

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 (38) hide show
  1. package/README.md +64 -0
  2. package/dist/BetterSqlite3Adapter-LUMODVC3.mjs +10 -0
  3. package/dist/BetterSqlite3Adapter-LUMODVC3.mjs.map +1 -0
  4. package/dist/chunk-5CZA6O2S.mjs +782 -0
  5. package/dist/chunk-5CZA6O2S.mjs.map +1 -0
  6. package/dist/chunk-73CP5EN6.mjs +227 -0
  7. package/dist/chunk-73CP5EN6.mjs.map +1 -0
  8. package/dist/chunk-FJ6ZGZIA.mjs +43 -0
  9. package/dist/chunk-FJ6ZGZIA.mjs.map +1 -0
  10. package/dist/chunk-IQNKZPW3.mjs +31660 -0
  11. package/dist/chunk-IQNKZPW3.mjs.map +1 -0
  12. package/dist/chunk-ZTICMRY6.mjs +7 -0
  13. package/dist/chunk-ZTICMRY6.mjs.map +1 -0
  14. package/dist/index.d.mts +5951 -1969
  15. package/dist/index.d.ts +5951 -1969
  16. package/dist/index.js +31309 -13744
  17. package/dist/index.js.map +1 -1
  18. package/dist/index.mjs +519 -15487
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/lib-ZCWT55TO.mjs +6 -0
  21. package/dist/lib-ZCWT55TO.mjs.map +1 -0
  22. package/dist/start-server.d.mts +2 -0
  23. package/dist/start-server.d.ts +2 -0
  24. package/dist/start-server.js +31751 -0
  25. package/dist/start-server.js.map +1 -0
  26. package/dist/start-server.mjs +112 -0
  27. package/dist/start-server.mjs.map +1 -0
  28. package/dist/workers/worker-scripts/base.worker.js +477 -0
  29. package/dist/workers/worker-scripts/base.worker.js.map +1 -0
  30. package/dist/workers/worker-scripts/crdt.worker.js +452 -0
  31. package/dist/workers/worker-scripts/crdt.worker.js.map +1 -0
  32. package/dist/workers/worker-scripts/merkle.worker.js +452 -0
  33. package/dist/workers/worker-scripts/merkle.worker.js.map +1 -0
  34. package/dist/workers/worker-scripts/serialization.worker.js +452 -0
  35. package/dist/workers/worker-scripts/serialization.worker.js.map +1 -0
  36. package/dist/workers/worker-scripts/test.worker.js +452 -0
  37. package/dist/workers/worker-scripts/test.worker.js.map +1 -0
  38. package/package.json +6 -3
@@ -0,0 +1,112 @@
1
+ import {
2
+ PostgresAdapter,
3
+ ServerFactory,
4
+ createBootstrapController,
5
+ logger,
6
+ validateEnv
7
+ } from "./chunk-IQNKZPW3.mjs";
8
+ import "./chunk-ZTICMRY6.mjs";
9
+ import "./chunk-FJ6ZGZIA.mjs";
10
+
11
+ // src/start-server.ts
12
+ var env = validateEnv();
13
+ var PORT = env.TOPGUN_PORT;
14
+ var CLUSTER_PORT = env.TOPGUN_CLUSTER_PORT;
15
+ var NODE_ID = env.NODE_ID || `node-${Math.random().toString(36).substring(2, 8)}`;
16
+ var PEERS = env.TOPGUN_PEERS ? env.TOPGUN_PEERS.split(",") : [];
17
+ var DISCOVERY_SERVICE = env.TOPGUN_DISCOVERY_SERVICE;
18
+ var DISCOVERY_INTERVAL = env.TOPGUN_DISCOVERY_INTERVAL;
19
+ var DISCOVERY_MODE = DISCOVERY_SERVICE ? "kubernetes" : "manual";
20
+ var DB_URL = env.DATABASE_URL;
21
+ var TLS_ENABLED = env.TOPGUN_TLS_ENABLED;
22
+ var TLS_CERT_PATH = env.TOPGUN_TLS_CERT_PATH;
23
+ var TLS_KEY_PATH = env.TOPGUN_TLS_KEY_PATH;
24
+ var TLS_CA_PATH = env.TOPGUN_TLS_CA_PATH;
25
+ var TLS_MIN_VERSION = env.TOPGUN_TLS_MIN_VERSION;
26
+ var TLS_PASSPHRASE = env.TOPGUN_TLS_PASSPHRASE;
27
+ var CLUSTER_TLS_ENABLED = env.TOPGUN_CLUSTER_TLS_ENABLED;
28
+ var CLUSTER_TLS_CERT_PATH = env.TOPGUN_CLUSTER_TLS_CERT_PATH || TLS_CERT_PATH;
29
+ var CLUSTER_TLS_KEY_PATH = env.TOPGUN_CLUSTER_TLS_KEY_PATH || TLS_KEY_PATH;
30
+ var CLUSTER_TLS_CA_PATH = env.TOPGUN_CLUSTER_TLS_CA_PATH || TLS_CA_PATH;
31
+ var CLUSTER_TLS_REQUIRE_CLIENT_CERT = env.TOPGUN_CLUSTER_MTLS;
32
+ var CLUSTER_TLS_REJECT_UNAUTHORIZED = env.TOPGUN_CLUSTER_TLS_REJECT_UNAUTHORIZED;
33
+ var tlsConfig;
34
+ if (TLS_ENABLED) {
35
+ tlsConfig = {
36
+ enabled: true,
37
+ certPath: TLS_CERT_PATH,
38
+ keyPath: TLS_KEY_PATH,
39
+ caCertPath: TLS_CA_PATH,
40
+ minVersion: TLS_MIN_VERSION,
41
+ passphrase: TLS_PASSPHRASE
42
+ };
43
+ logger.info({ certPath: TLS_CERT_PATH, minVersion: TLS_MIN_VERSION }, "Client TLS configured");
44
+ }
45
+ var clusterTlsConfig;
46
+ if (CLUSTER_TLS_ENABLED) {
47
+ clusterTlsConfig = {
48
+ enabled: true,
49
+ certPath: CLUSTER_TLS_CERT_PATH,
50
+ keyPath: CLUSTER_TLS_KEY_PATH,
51
+ caCertPath: CLUSTER_TLS_CA_PATH,
52
+ minVersion: TLS_MIN_VERSION,
53
+ passphrase: TLS_PASSPHRASE,
54
+ requireClientCert: CLUSTER_TLS_REQUIRE_CLIENT_CERT,
55
+ rejectUnauthorized: CLUSTER_TLS_REJECT_UNAUTHORIZED
56
+ };
57
+ logger.info({
58
+ certPath: CLUSTER_TLS_CERT_PATH,
59
+ mTLS: CLUSTER_TLS_REQUIRE_CLIENT_CERT
60
+ }, "Cluster TLS configured");
61
+ }
62
+ async function main() {
63
+ const bootstrapController = createBootstrapController();
64
+ await bootstrapController.checkAutoSetup();
65
+ let storage;
66
+ if (DB_URL) {
67
+ storage = new PostgresAdapter({ connectionString: DB_URL });
68
+ logger.info("Using PostgresAdapter with DATABASE_URL");
69
+ } else {
70
+ logger.info("No DATABASE_URL provided, using in-memory storage (non-persistent)");
71
+ }
72
+ const server = ServerFactory.create({
73
+ port: PORT,
74
+ clusterPort: CLUSTER_PORT,
75
+ nodeId: NODE_ID,
76
+ peers: PEERS,
77
+ discovery: DISCOVERY_MODE,
78
+ serviceName: DISCOVERY_SERVICE,
79
+ discoveryInterval: DISCOVERY_INTERVAL,
80
+ storage,
81
+ host: "0.0.0.0",
82
+ // Bind to all interfaces in Docker
83
+ securityPolicies: [
84
+ // Default permissive policy for now - in prod this should be configured
85
+ {
86
+ role: "USER",
87
+ mapNamePattern: "*",
88
+ actions: ["ALL"]
89
+ }
90
+ ],
91
+ tls: tlsConfig,
92
+ clusterTls: clusterTlsConfig
93
+ });
94
+ const shutdown = async (signal) => {
95
+ logger.info({ signal }, "Starting graceful shutdown");
96
+ try {
97
+ await server.shutdown();
98
+ process.exit(0);
99
+ } catch (err) {
100
+ logger.error({ err }, "Error during shutdown");
101
+ process.exit(1);
102
+ }
103
+ };
104
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
105
+ process.on("SIGINT", () => shutdown("SIGINT"));
106
+ logger.info({ port: PORT, clusterPort: CLUSTER_PORT, nodeId: NODE_ID, discovery: DISCOVERY_MODE }, "TopGun Server Starting");
107
+ }
108
+ main().catch((err) => {
109
+ logger.error({ err }, "Failed to start server");
110
+ process.exit(1);
111
+ });
112
+ //# sourceMappingURL=start-server.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/start-server.ts"],"sourcesContent":["import { ServerFactory } from './ServerFactory';\nimport { PostgresAdapter } from './storage/PostgresAdapter';\nimport { logger } from './utils/logger';\nimport { TLSConfig, ClusterTLSConfig } from './types/TLSConfig';\nimport { createBootstrapController } from './bootstrap';\nimport { validateEnv } from './config';\n\n// Validate environment variables\nconst env = validateEnv();\n\n// Configuration\nconst PORT = env.TOPGUN_PORT;\nconst CLUSTER_PORT = env.TOPGUN_CLUSTER_PORT;\nconst NODE_ID = env.NODE_ID || `node-${Math.random().toString(36).substring(2, 8)}`;\nconst PEERS = env.TOPGUN_PEERS ? env.TOPGUN_PEERS.split(',') : [];\nconst DISCOVERY_SERVICE = env.TOPGUN_DISCOVERY_SERVICE;\nconst DISCOVERY_INTERVAL = env.TOPGUN_DISCOVERY_INTERVAL;\nconst DISCOVERY_MODE = DISCOVERY_SERVICE ? 'kubernetes' : 'manual';\n\nconst DB_URL = env.DATABASE_URL;\n\n// TLS Configuration\nconst TLS_ENABLED = env.TOPGUN_TLS_ENABLED;\nconst TLS_CERT_PATH = env.TOPGUN_TLS_CERT_PATH;\nconst TLS_KEY_PATH = env.TOPGUN_TLS_KEY_PATH;\nconst TLS_CA_PATH = env.TOPGUN_TLS_CA_PATH;\nconst TLS_MIN_VERSION = env.TOPGUN_TLS_MIN_VERSION;\nconst TLS_PASSPHRASE = env.TOPGUN_TLS_PASSPHRASE;\n\n// Cluster TLS (can use same certs or separate)\nconst CLUSTER_TLS_ENABLED = env.TOPGUN_CLUSTER_TLS_ENABLED;\nconst CLUSTER_TLS_CERT_PATH = env.TOPGUN_CLUSTER_TLS_CERT_PATH || TLS_CERT_PATH;\nconst CLUSTER_TLS_KEY_PATH = env.TOPGUN_CLUSTER_TLS_KEY_PATH || TLS_KEY_PATH;\nconst CLUSTER_TLS_CA_PATH = env.TOPGUN_CLUSTER_TLS_CA_PATH || TLS_CA_PATH;\nconst CLUSTER_TLS_REQUIRE_CLIENT_CERT = env.TOPGUN_CLUSTER_MTLS;\nconst CLUSTER_TLS_REJECT_UNAUTHORIZED = env.TOPGUN_CLUSTER_TLS_REJECT_UNAUTHORIZED;\n\n// Build TLS Config\nlet tlsConfig: TLSConfig | undefined;\nif (TLS_ENABLED) {\n tlsConfig = {\n enabled: true,\n certPath: TLS_CERT_PATH!,\n keyPath: TLS_KEY_PATH!,\n caCertPath: TLS_CA_PATH,\n minVersion: TLS_MIN_VERSION,\n passphrase: TLS_PASSPHRASE,\n };\n\n logger.info({ certPath: TLS_CERT_PATH, minVersion: TLS_MIN_VERSION }, 'Client TLS configured');\n}\n\n// Build Cluster TLS Config\nlet clusterTlsConfig: ClusterTLSConfig | undefined;\nif (CLUSTER_TLS_ENABLED) {\n clusterTlsConfig = {\n enabled: true,\n certPath: CLUSTER_TLS_CERT_PATH!,\n keyPath: CLUSTER_TLS_KEY_PATH!,\n caCertPath: CLUSTER_TLS_CA_PATH,\n minVersion: TLS_MIN_VERSION,\n passphrase: TLS_PASSPHRASE,\n requireClientCert: CLUSTER_TLS_REQUIRE_CLIENT_CERT,\n rejectUnauthorized: CLUSTER_TLS_REJECT_UNAUTHORIZED,\n };\n\n logger.info({\n certPath: CLUSTER_TLS_CERT_PATH,\n mTLS: CLUSTER_TLS_REQUIRE_CLIENT_CERT\n }, 'Cluster TLS configured');\n}\n\n// Main startup function (async to support auto-setup)\nasync function main() {\n // Zero-Touch Setup\n // Run auto-setup before creating ServerCoordinator\n const bootstrapController = createBootstrapController();\n await bootstrapController.checkAutoSetup();\n\n // Setup Storage\n let storage;\n if (DB_URL) {\n storage = new PostgresAdapter({ connectionString: DB_URL });\n logger.info('Using PostgresAdapter with DATABASE_URL');\n } else {\n logger.info('No DATABASE_URL provided, using in-memory storage (non-persistent)');\n }\n\n const server = ServerFactory.create({\n port: PORT,\n clusterPort: CLUSTER_PORT,\n nodeId: NODE_ID,\n peers: PEERS,\n discovery: DISCOVERY_MODE,\n serviceName: DISCOVERY_SERVICE,\n discoveryInterval: DISCOVERY_INTERVAL,\n storage,\n host: '0.0.0.0', // Bind to all interfaces in Docker\n securityPolicies: [\n // Default permissive policy for now - in prod this should be configured\n {\n role: 'USER',\n mapNamePattern: '*',\n actions: ['ALL']\n }\n ],\n tls: tlsConfig,\n clusterTls: clusterTlsConfig,\n });\n\n // Graceful Shutdown\n const shutdown = async (signal: string) => {\n logger.info({ signal }, 'Starting graceful shutdown');\n try {\n await server.shutdown();\n process.exit(0);\n } catch (err) {\n logger.error({ err }, 'Error during shutdown');\n process.exit(1);\n }\n };\n\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n process.on('SIGINT', () => shutdown('SIGINT'));\n\n logger.info({ port: PORT, clusterPort: CLUSTER_PORT, nodeId: NODE_ID, discovery: DISCOVERY_MODE }, 'TopGun Server Starting');\n}\n\n// Run main and handle errors\nmain().catch((err) => {\n logger.error({ err }, 'Failed to start server');\n process.exit(1);\n});\n\n"],"mappings":"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","names":[]}
@@ -0,0 +1,477 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __esm = (fn, res) => function __init() {
7
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ };
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
+
23
+ // src/workers/worker-scripts/crdt.worker.ts
24
+ var crdt_worker_exports = {};
25
+ function compareTimestamps(a, b) {
26
+ if (a.millis !== b.millis) {
27
+ return a.millis - b.millis;
28
+ }
29
+ if (a.counter !== b.counter) {
30
+ return a.counter - b.counter;
31
+ }
32
+ return a.nodeId.localeCompare(b.nodeId);
33
+ }
34
+ var init_crdt_worker = __esm({
35
+ "src/workers/worker-scripts/crdt.worker.ts"() {
36
+ "use strict";
37
+ init_base_worker();
38
+ registerHandler("lww-merge", (payload) => {
39
+ const { records, existingState } = payload;
40
+ const existingMap = /* @__PURE__ */ new Map();
41
+ for (const existing of existingState) {
42
+ existingMap.set(existing.key, {
43
+ value: existing.value,
44
+ timestamp: existing.timestamp,
45
+ ttlMs: existing.ttlMs
46
+ });
47
+ }
48
+ const toApply = [];
49
+ const conflicts = [];
50
+ let skipped = 0;
51
+ for (const record of records) {
52
+ const existing = existingMap.get(record.key);
53
+ if (!existing) {
54
+ toApply.push({
55
+ key: record.key,
56
+ value: record.value,
57
+ timestamp: record.timestamp,
58
+ ttlMs: record.ttlMs
59
+ });
60
+ existingMap.set(record.key, {
61
+ value: record.value,
62
+ timestamp: record.timestamp,
63
+ ttlMs: record.ttlMs
64
+ });
65
+ continue;
66
+ }
67
+ const cmp = compareTimestamps(record.timestamp, existing.timestamp);
68
+ const isConflict = record.timestamp.millis === existing.timestamp.millis && (record.timestamp.counter !== existing.timestamp.counter || record.timestamp.nodeId !== existing.timestamp.nodeId);
69
+ if (cmp > 0) {
70
+ toApply.push({
71
+ key: record.key,
72
+ value: record.value,
73
+ timestamp: record.timestamp,
74
+ ttlMs: record.ttlMs
75
+ });
76
+ existingMap.set(record.key, {
77
+ value: record.value,
78
+ timestamp: record.timestamp,
79
+ ttlMs: record.ttlMs
80
+ });
81
+ if (isConflict) {
82
+ conflicts.push(record.key);
83
+ }
84
+ } else if (cmp === 0) {
85
+ conflicts.push(record.key);
86
+ skipped++;
87
+ } else {
88
+ if (isConflict) {
89
+ conflicts.push(record.key);
90
+ }
91
+ skipped++;
92
+ }
93
+ }
94
+ return {
95
+ toApply,
96
+ skipped,
97
+ conflicts
98
+ };
99
+ });
100
+ registerHandler("ormap-merge", (payload) => {
101
+ const {
102
+ items,
103
+ tombstones,
104
+ existingTags,
105
+ existingTombstones
106
+ } = payload;
107
+ const tagSet = new Set(existingTags);
108
+ const tombstoneSet = new Set(existingTombstones);
109
+ const itemsToApply = [];
110
+ const tombstonesToApply = [];
111
+ const tagsToRemove = [];
112
+ let itemsSkipped = 0;
113
+ let tombstonesSkipped = 0;
114
+ for (const tombstone of tombstones) {
115
+ if (tombstoneSet.has(tombstone.tag)) {
116
+ tombstonesSkipped++;
117
+ continue;
118
+ }
119
+ tombstonesToApply.push(tombstone.tag);
120
+ tombstoneSet.add(tombstone.tag);
121
+ if (tagSet.has(tombstone.tag)) {
122
+ tagsToRemove.push(tombstone.tag);
123
+ tagSet.delete(tombstone.tag);
124
+ }
125
+ }
126
+ for (const item of items) {
127
+ if (tombstoneSet.has(item.tag)) {
128
+ itemsSkipped++;
129
+ continue;
130
+ }
131
+ if (tagSet.has(item.tag)) {
132
+ itemsSkipped++;
133
+ continue;
134
+ }
135
+ itemsToApply.push({
136
+ key: item.key,
137
+ value: item.value,
138
+ timestamp: item.timestamp,
139
+ tag: item.tag,
140
+ ttlMs: item.ttlMs
141
+ });
142
+ tagSet.add(item.tag);
143
+ }
144
+ return {
145
+ itemsToApply,
146
+ tombstonesToApply,
147
+ tagsToRemove,
148
+ itemsSkipped,
149
+ tombstonesSkipped
150
+ };
151
+ });
152
+ }
153
+ });
154
+
155
+ // src/workers/worker-scripts/merkle.worker.ts
156
+ var merkle_worker_exports = {};
157
+ function hashString(str) {
158
+ let hash = 2166136261;
159
+ for (let i = 0; i < str.length; i++) {
160
+ hash ^= str.charCodeAt(i);
161
+ hash = Math.imul(hash, 16777619);
162
+ }
163
+ return hash >>> 0;
164
+ }
165
+ function computeItemHash(key, millis, counter, nodeId) {
166
+ return hashString(`${key}:${millis}:${counter}:${nodeId}`);
167
+ }
168
+ function computeORMapEntryHash(key, records) {
169
+ const sortedRecords = [...records].sort((a, b) => a.tag.localeCompare(b.tag));
170
+ let combinedStr = key;
171
+ for (const record of sortedRecords) {
172
+ combinedStr += `:${record.tag}:${record.timestamp.millis}:${record.timestamp.counter}:${record.timestamp.nodeId}`;
173
+ }
174
+ return hashString(combinedStr);
175
+ }
176
+ function buildMerkleTree(entries, depth) {
177
+ const root = { hash: 0, children: {} };
178
+ const buckets = /* @__PURE__ */ new Map();
179
+ for (const { key, hash: itemHash } of entries) {
180
+ const pathHash = hashString(key).toString(16).padStart(8, "0");
181
+ updateNode(root, key, itemHash, pathHash, 0, depth);
182
+ }
183
+ collectBuckets(root, "", depth, buckets);
184
+ return { root, buckets };
185
+ }
186
+ function updateNode(node, key, itemHash, pathHash, level, depth) {
187
+ if (level >= depth) {
188
+ if (!node.entries) node.entries = /* @__PURE__ */ new Map();
189
+ node.entries.set(key, itemHash);
190
+ let h2 = 0;
191
+ for (const val of node.entries.values()) {
192
+ h2 = h2 + val | 0;
193
+ }
194
+ node.hash = h2 >>> 0;
195
+ return node.hash;
196
+ }
197
+ const bucketChar = pathHash[level];
198
+ if (!node.children) node.children = {};
199
+ if (!node.children[bucketChar]) {
200
+ node.children[bucketChar] = { hash: 0 };
201
+ }
202
+ updateNode(node.children[bucketChar], key, itemHash, pathHash, level + 1, depth);
203
+ let h = 0;
204
+ for (const child of Object.values(node.children)) {
205
+ h = h + child.hash | 0;
206
+ }
207
+ node.hash = h >>> 0;
208
+ return node.hash;
209
+ }
210
+ function collectBuckets(node, path, depth, buckets) {
211
+ if (path.length >= depth) {
212
+ if (node.entries && node.entries.size > 0) {
213
+ buckets.set(path, {
214
+ hash: node.hash,
215
+ keys: Array.from(node.entries.keys())
216
+ });
217
+ }
218
+ return;
219
+ }
220
+ if (node.children) {
221
+ for (const [char, child] of Object.entries(node.children)) {
222
+ collectBuckets(child, path + char, depth, buckets);
223
+ }
224
+ }
225
+ }
226
+ var init_merkle_worker = __esm({
227
+ "src/workers/worker-scripts/merkle.worker.ts"() {
228
+ "use strict";
229
+ init_base_worker();
230
+ registerHandler("merkle-hash", (payload) => {
231
+ const { entries, depth = 3 } = payload;
232
+ const hashEntries = [];
233
+ const hashes = [];
234
+ for (const entry of entries) {
235
+ const itemHash = computeItemHash(
236
+ entry.key,
237
+ entry.timestamp.millis,
238
+ entry.timestamp.counter,
239
+ entry.timestamp.nodeId
240
+ );
241
+ hashEntries.push({ key: entry.key, hash: itemHash });
242
+ hashes.push([entry.key, itemHash]);
243
+ }
244
+ const { root, buckets } = buildMerkleTree(hashEntries, depth);
245
+ return {
246
+ hashes,
247
+ rootHash: root.hash,
248
+ buckets: Array.from(buckets.entries())
249
+ };
250
+ });
251
+ registerHandler("merkle-hash-ormap", (payload) => {
252
+ const { entries, depth = 3 } = payload;
253
+ const hashEntries = [];
254
+ const hashes = [];
255
+ for (const entry of entries) {
256
+ const entryHash = computeORMapEntryHash(entry.key, entry.records);
257
+ hashEntries.push({ key: entry.key, hash: entryHash });
258
+ hashes.push([entry.key, entryHash]);
259
+ }
260
+ const { root, buckets } = buildMerkleTree(hashEntries, depth);
261
+ return {
262
+ hashes,
263
+ rootHash: root.hash,
264
+ buckets: Array.from(buckets.entries())
265
+ };
266
+ });
267
+ registerHandler("merkle-diff", (payload) => {
268
+ const { localBuckets, remoteBuckets } = payload;
269
+ const localMap = new Map(localBuckets);
270
+ const remoteMap = new Map(remoteBuckets);
271
+ const missingLocal = [];
272
+ const missingRemote = [];
273
+ const differingPaths = [];
274
+ for (const [path, remoteBucket] of remoteMap) {
275
+ const localBucket = localMap.get(path);
276
+ if (!localBucket) {
277
+ missingLocal.push(...remoteBucket.keys);
278
+ } else if (localBucket.hash !== remoteBucket.hash) {
279
+ differingPaths.push(path);
280
+ const localKeys = new Set(localBucket.keys);
281
+ const remoteKeys = new Set(remoteBucket.keys);
282
+ for (const key of remoteKeys) {
283
+ if (!localKeys.has(key)) {
284
+ missingLocal.push(key);
285
+ }
286
+ }
287
+ for (const key of localKeys) {
288
+ if (!remoteKeys.has(key)) {
289
+ missingRemote.push(key);
290
+ }
291
+ }
292
+ }
293
+ }
294
+ for (const [path, localBucket] of localMap) {
295
+ if (!remoteMap.has(path)) {
296
+ missingRemote.push(...localBucket.keys);
297
+ }
298
+ }
299
+ return {
300
+ missingLocal,
301
+ missingRemote,
302
+ differingPaths
303
+ };
304
+ });
305
+ registerHandler("merkle-rebuild", (payload) => {
306
+ const { records, depth = 3 } = payload;
307
+ const hashEntries = [];
308
+ for (const record of records) {
309
+ const itemHash = computeItemHash(
310
+ record.key,
311
+ record.timestamp.millis,
312
+ record.timestamp.counter,
313
+ record.timestamp.nodeId
314
+ );
315
+ hashEntries.push({ key: record.key, hash: itemHash });
316
+ }
317
+ const { root, buckets } = buildMerkleTree(hashEntries, depth);
318
+ return {
319
+ rootHash: root.hash,
320
+ buckets: Array.from(buckets.entries())
321
+ };
322
+ });
323
+ registerHandler("merkle-rebuild-ormap", (payload) => {
324
+ const { records, depth = 3 } = payload;
325
+ const hashEntries = [];
326
+ for (const record of records) {
327
+ const entryHash = computeORMapEntryHash(record.key, record.tags);
328
+ hashEntries.push({ key: record.key, hash: entryHash });
329
+ }
330
+ const { root, buckets } = buildMerkleTree(hashEntries, depth);
331
+ return {
332
+ rootHash: root.hash,
333
+ buckets: Array.from(buckets.entries())
334
+ };
335
+ });
336
+ }
337
+ });
338
+
339
+ // src/workers/worker-scripts/serialization.worker.ts
340
+ var serialization_worker_exports = {};
341
+ function uint8ArrayToBase64(bytes) {
342
+ let binary = "";
343
+ for (let i = 0; i < bytes.length; i++) {
344
+ binary += String.fromCharCode(bytes[i]);
345
+ }
346
+ return btoa(binary);
347
+ }
348
+ function base64ToUint8Array(base64) {
349
+ const binary = atob(base64);
350
+ const bytes = new Uint8Array(binary.length);
351
+ for (let i = 0; i < binary.length; i++) {
352
+ bytes[i] = binary.charCodeAt(i);
353
+ }
354
+ return bytes;
355
+ }
356
+ var import_core;
357
+ var init_serialization_worker = __esm({
358
+ "src/workers/worker-scripts/serialization.worker.ts"() {
359
+ "use strict";
360
+ init_base_worker();
361
+ import_core = require("@topgunbuild/core");
362
+ registerHandler("serialize", (payload) => {
363
+ const { items } = payload;
364
+ const serialized = [];
365
+ for (const item of items) {
366
+ const bytes = (0, import_core.serialize)(item);
367
+ serialized.push(uint8ArrayToBase64(bytes));
368
+ }
369
+ return { serialized };
370
+ });
371
+ registerHandler("deserialize", (payload) => {
372
+ const { items } = payload;
373
+ const deserialized = [];
374
+ for (const item of items) {
375
+ const bytes = base64ToUint8Array(item);
376
+ deserialized.push((0, import_core.deserialize)(bytes));
377
+ }
378
+ return { deserialized };
379
+ });
380
+ }
381
+ });
382
+
383
+ // src/workers/worker-scripts/test.worker.ts
384
+ var test_worker_exports = {};
385
+ var init_test_worker = __esm({
386
+ "src/workers/worker-scripts/test.worker.ts"() {
387
+ "use strict";
388
+ init_base_worker();
389
+ registerHandler("echo", (payload) => {
390
+ return payload;
391
+ });
392
+ registerHandler("delayed-echo", async (payload) => {
393
+ const { data, delay } = payload;
394
+ await new Promise((resolve) => setTimeout(resolve, delay));
395
+ return data;
396
+ });
397
+ registerHandler("throw-error", (payload) => {
398
+ const { message } = payload;
399
+ throw new Error(message);
400
+ });
401
+ registerHandler("cpu-work", (payload) => {
402
+ const { iterations } = payload;
403
+ let result = 0;
404
+ for (let i = 0; i < iterations; i++) {
405
+ result += Math.sqrt(i);
406
+ }
407
+ return result;
408
+ });
409
+ registerHandler("return-undefined", () => {
410
+ return void 0;
411
+ });
412
+ registerHandler("return-null", () => {
413
+ return null;
414
+ });
415
+ }
416
+ });
417
+
418
+ // src/workers/worker-scripts/base.worker.ts
419
+ var base_worker_exports = {};
420
+ __export(base_worker_exports, {
421
+ handlers: () => handlers,
422
+ hasHandler: () => hasHandler,
423
+ registerHandler: () => registerHandler,
424
+ unregisterHandler: () => unregisterHandler
425
+ });
426
+ module.exports = __toCommonJS(base_worker_exports);
427
+ function registerHandler(type, handler) {
428
+ handlers.set(type, handler);
429
+ }
430
+ function unregisterHandler(type) {
431
+ handlers.delete(type);
432
+ }
433
+ function hasHandler(type) {
434
+ return handlers.has(type);
435
+ }
436
+ var import_worker_threads, handlers;
437
+ var init_base_worker = __esm({
438
+ "src/workers/worker-scripts/base.worker.ts"() {
439
+ import_worker_threads = require("worker_threads");
440
+ handlers = /* @__PURE__ */ new Map();
441
+ if (import_worker_threads.parentPort) {
442
+ import_worker_threads.parentPort.on("message", async (task) => {
443
+ const { id, type, payload } = task;
444
+ const response = {
445
+ id,
446
+ success: false
447
+ };
448
+ try {
449
+ const handler = handlers.get(type);
450
+ if (!handler) {
451
+ throw new Error(`Unknown task type: ${type}`);
452
+ }
453
+ const result = await handler(payload);
454
+ response.success = true;
455
+ response.result = result;
456
+ } catch (error) {
457
+ response.success = false;
458
+ response.error = error instanceof Error ? error.message : String(error);
459
+ }
460
+ import_worker_threads.parentPort.postMessage(response);
461
+ });
462
+ }
463
+ init_crdt_worker();
464
+ init_merkle_worker();
465
+ init_serialization_worker();
466
+ init_test_worker();
467
+ }
468
+ });
469
+ init_base_worker();
470
+ // Annotate the CommonJS export names for ESM import in node:
471
+ 0 && (module.exports = {
472
+ handlers,
473
+ hasHandler,
474
+ registerHandler,
475
+ unregisterHandler
476
+ });
477
+ //# sourceMappingURL=base.worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/workers/worker-scripts/crdt.worker.ts","../../../src/workers/worker-scripts/merkle.worker.ts","../../../src/workers/worker-scripts/serialization.worker.ts","../../../src/workers/worker-scripts/test.worker.ts","../../../src/workers/worker-scripts/base.worker.ts"],"sourcesContent":["/**\n * CRDT Merge Worker Script\n * CRDTMergeWorker Implementation\n *\n * Handles CPU-intensive CRDT merge operations:\n * - lww-merge: Merge LWWMap records (Last-Write-Wins)\n * - ormap-merge: Merge ORMap items and tombstones\n */\n\nimport { registerHandler } from './base.worker';\nimport type {\n LWWMergePayload,\n LWWMergeResult,\n ORMapMergePayload,\n ORMapMergeResult,\n} from '../crdt-types';\n\n// ============ Timestamp Comparison ============\n\ninterface Timestamp {\n millis: number;\n counter: number;\n nodeId: string;\n}\n\n/**\n * Compare two timestamps (same logic as HLC.compare)\n * Returns:\n * < 0 if a < b\n * > 0 if a > b\n * = 0 if a === b\n */\nfunction compareTimestamps(a: Timestamp, b: Timestamp): number {\n if (a.millis !== b.millis) {\n return a.millis - b.millis;\n }\n if (a.counter !== b.counter) {\n return a.counter - b.counter;\n }\n return a.nodeId.localeCompare(b.nodeId);\n}\n\n// ============ Handler: lww-merge ============\n\nregisterHandler('lww-merge', (payload: unknown): LWWMergeResult => {\n const { records, existingState } = payload as LWWMergePayload;\n\n // Build existing state map for O(1) lookup\n const existingMap = new Map<string, {\n value: unknown;\n timestamp: Timestamp;\n ttlMs?: number;\n }>();\n\n for (const existing of existingState) {\n existingMap.set(existing.key, {\n value: existing.value,\n timestamp: existing.timestamp,\n ttlMs: existing.ttlMs,\n });\n }\n\n const toApply: LWWMergeResult['toApply'] = [];\n const conflicts: string[] = [];\n let skipped = 0;\n\n for (const record of records) {\n const existing = existingMap.get(record.key);\n\n if (!existing) {\n // No existing record - apply new one\n toApply.push({\n key: record.key,\n value: record.value,\n timestamp: record.timestamp,\n ttlMs: record.ttlMs,\n });\n // Update existingMap for subsequent records in batch\n existingMap.set(record.key, {\n value: record.value,\n timestamp: record.timestamp,\n ttlMs: record.ttlMs,\n });\n continue;\n }\n\n const cmp = compareTimestamps(record.timestamp, existing.timestamp);\n\n // Detect conflict: same millis but different counter/nodeId (concurrent writes)\n const isConflict = record.timestamp.millis === existing.timestamp.millis &&\n (record.timestamp.counter !== existing.timestamp.counter ||\n record.timestamp.nodeId !== existing.timestamp.nodeId);\n\n if (cmp > 0) {\n // New record is newer - apply it\n toApply.push({\n key: record.key,\n value: record.value,\n timestamp: record.timestamp,\n ttlMs: record.ttlMs,\n });\n // Update for subsequent records\n existingMap.set(record.key, {\n value: record.value,\n timestamp: record.timestamp,\n ttlMs: record.ttlMs,\n });\n if (isConflict) {\n conflicts.push(record.key);\n }\n } else if (cmp === 0) {\n // Same timestamp - this is a conflict\n conflicts.push(record.key);\n skipped++;\n } else {\n // New record is older - skip\n if (isConflict) {\n conflicts.push(record.key);\n }\n skipped++;\n }\n }\n\n return {\n toApply,\n skipped,\n conflicts,\n };\n});\n\n// ============ Handler: ormap-merge ============\n\nregisterHandler('ormap-merge', (payload: unknown): ORMapMergeResult => {\n const {\n items,\n tombstones,\n existingTags,\n existingTombstones,\n } = payload as ORMapMergePayload;\n\n // Build sets for O(1) lookup\n const tagSet = new Set(existingTags);\n const tombstoneSet = new Set(existingTombstones);\n\n const itemsToApply: ORMapMergeResult['itemsToApply'] = [];\n const tombstonesToApply: string[] = [];\n const tagsToRemove: string[] = [];\n let itemsSkipped = 0;\n let tombstonesSkipped = 0;\n\n // Process tombstones first (they take precedence)\n for (const tombstone of tombstones) {\n if (tombstoneSet.has(tombstone.tag)) {\n // Already have this tombstone\n tombstonesSkipped++;\n continue;\n }\n\n // New tombstone - should be applied\n tombstonesToApply.push(tombstone.tag);\n tombstoneSet.add(tombstone.tag);\n\n // If this tag exists in items, mark for removal\n if (tagSet.has(tombstone.tag)) {\n tagsToRemove.push(tombstone.tag);\n tagSet.delete(tombstone.tag);\n }\n }\n\n // Process items\n for (const item of items) {\n // Check if tag is tombstoned\n if (tombstoneSet.has(item.tag)) {\n itemsSkipped++;\n continue;\n }\n\n // Check if tag already exists\n if (tagSet.has(item.tag)) {\n // Tag already exists - OR-Map semantics: same tag = same item\n // We could update value if timestamp is newer, but in pure ORMap\n // the tag is unique and immutable\n itemsSkipped++;\n continue;\n }\n\n // New item - apply it\n itemsToApply.push({\n key: item.key,\n value: item.value,\n timestamp: item.timestamp,\n tag: item.tag,\n ttlMs: item.ttlMs,\n });\n tagSet.add(item.tag);\n }\n\n return {\n itemsToApply,\n tombstonesToApply,\n tagsToRemove,\n itemsSkipped,\n tombstonesSkipped,\n };\n});\n","/**\n * Merkle Worker Script\n * MerkleWorker Implementation\n *\n * Handles CPU-intensive Merkle tree operations:\n * - merkle-hash: Compute hashes for batch of LWWMap entries\n * - merkle-hash-ormap: Compute hashes for batch of ORMap entries\n * - merkle-diff: Find differences between local and remote trees\n * - merkle-rebuild: Rebuild tree from records\n */\n\nimport { registerHandler } from './base.worker';\nimport type {\n MerkleHashPayload,\n MerkleHashResult,\n ORMapMerkleHashPayload,\n ORMapMerkleHashResult,\n MerkleDiffPayload,\n MerkleDiffResult,\n MerkleRebuildPayload,\n MerkleRebuildResult,\n ORMapMerkleRebuildPayload,\n BucketInfo,\n} from '../merkle-types';\n\n// ============ Hash Functions (same as core) ============\n\n/**\n * FNV-1a Hash implementation for strings.\n * Identical to packages/core/src/utils/hash.ts\n */\nfunction hashString(str: string): number {\n let hash = 0x811c9dc5;\n for (let i = 0; i < str.length; i++) {\n hash ^= str.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193);\n }\n return hash >>> 0;\n}\n\n/**\n * Compute item hash for LWWMap entry.\n * Same as in MerkleTree.update()\n */\nfunction computeItemHash(\n key: string,\n millis: number,\n counter: number,\n nodeId: string\n): number {\n return hashString(`${key}:${millis}:${counter}:${nodeId}`);\n}\n\n/**\n * Compute entry hash for ORMap entry.\n * Same as hashORMapEntry in ORMapMerkle.ts\n */\nfunction computeORMapEntryHash(\n key: string,\n records: Array<{ tag: string; timestamp: { millis: number; counter: number; nodeId: string } }>\n): number {\n // Sort records by tag for deterministic hashing\n const sortedRecords = [...records].sort((a, b) => a.tag.localeCompare(b.tag));\n\n let combinedStr = key;\n for (const record of sortedRecords) {\n combinedStr += `:${record.tag}:${record.timestamp.millis}:${record.timestamp.counter}:${record.timestamp.nodeId}`;\n }\n\n return hashString(combinedStr);\n}\n\n// ============ Merkle Tree Node Structure ============\n\ninterface MerkleNode {\n hash: number;\n children?: { [key: string]: MerkleNode };\n entries?: Map<string, number>;\n}\n\n/**\n * Build a Merkle tree from entries\n */\nfunction buildMerkleTree(\n entries: Array<{ key: string; hash: number }>,\n depth: number\n): { root: MerkleNode; buckets: Map<string, { hash: number; keys: string[] }> } {\n const root: MerkleNode = { hash: 0, children: {} };\n const buckets = new Map<string, { hash: number; keys: string[] }>();\n\n for (const { key, hash: itemHash } of entries) {\n const pathHash = hashString(key).toString(16).padStart(8, '0');\n updateNode(root, key, itemHash, pathHash, 0, depth);\n }\n\n // Collect buckets at leaf level\n collectBuckets(root, '', depth, buckets);\n\n return { root, buckets };\n}\n\nfunction updateNode(\n node: MerkleNode,\n key: string,\n itemHash: number,\n pathHash: string,\n level: number,\n depth: number\n): number {\n // Leaf Node Logic\n if (level >= depth) {\n if (!node.entries) node.entries = new Map();\n node.entries.set(key, itemHash);\n\n // Recalculate leaf hash (Sum of item hashes)\n let h = 0;\n for (const val of node.entries.values()) {\n h = (h + val) | 0;\n }\n node.hash = h >>> 0;\n return node.hash;\n }\n\n // Intermediate Node Logic\n const bucketChar = pathHash[level];\n if (!node.children) node.children = {};\n\n if (!node.children[bucketChar]) {\n node.children[bucketChar] = { hash: 0 };\n }\n\n updateNode(node.children[bucketChar], key, itemHash, pathHash, level + 1, depth);\n\n // Recalculate this node's hash from children\n let h = 0;\n for (const child of Object.values(node.children)) {\n h = (h + child.hash) | 0;\n }\n node.hash = h >>> 0;\n return node.hash;\n}\n\nfunction collectBuckets(\n node: MerkleNode,\n path: string,\n depth: number,\n buckets: Map<string, { hash: number; keys: string[] }>\n): void {\n if (path.length >= depth) {\n // Leaf level\n if (node.entries && node.entries.size > 0) {\n buckets.set(path, {\n hash: node.hash,\n keys: Array.from(node.entries.keys()),\n });\n }\n return;\n }\n\n if (node.children) {\n for (const [char, child] of Object.entries(node.children)) {\n collectBuckets(child, path + char, depth, buckets);\n }\n }\n}\n\n// ============ Handler: merkle-hash (LWWMap) ============\n\nregisterHandler('merkle-hash', (payload: unknown): MerkleHashResult => {\n const { entries, depth = 3 } = payload as MerkleHashPayload;\n\n // Compute hashes for each entry\n const hashEntries: Array<{ key: string; hash: number }> = [];\n const hashes: Array<[string, number]> = [];\n\n for (const entry of entries) {\n const itemHash = computeItemHash(\n entry.key,\n entry.timestamp.millis,\n entry.timestamp.counter,\n entry.timestamp.nodeId\n );\n hashEntries.push({ key: entry.key, hash: itemHash });\n hashes.push([entry.key, itemHash]);\n }\n\n // Build tree\n const { root, buckets } = buildMerkleTree(hashEntries, depth);\n\n return {\n hashes,\n rootHash: root.hash,\n buckets: Array.from(buckets.entries()),\n };\n});\n\n// ============ Handler: merkle-hash-ormap ============\n\nregisterHandler('merkle-hash-ormap', (payload: unknown): ORMapMerkleHashResult => {\n const { entries, depth = 3 } = payload as ORMapMerkleHashPayload;\n\n // Compute hashes for each entry\n const hashEntries: Array<{ key: string; hash: number }> = [];\n const hashes: Array<[string, number]> = [];\n\n for (const entry of entries) {\n const entryHash = computeORMapEntryHash(entry.key, entry.records);\n hashEntries.push({ key: entry.key, hash: entryHash });\n hashes.push([entry.key, entryHash]);\n }\n\n // Build tree\n const { root, buckets } = buildMerkleTree(hashEntries, depth);\n\n return {\n hashes,\n rootHash: root.hash,\n buckets: Array.from(buckets.entries()),\n };\n});\n\n// ============ Handler: merkle-diff ============\n\nregisterHandler('merkle-diff', (payload: unknown): MerkleDiffResult => {\n const { localBuckets, remoteBuckets } = payload as MerkleDiffPayload;\n\n const localMap = new Map<string, BucketInfo>(localBuckets);\n const remoteMap = new Map<string, BucketInfo>(remoteBuckets);\n\n const missingLocal: string[] = [];\n const missingRemote: string[] = [];\n const differingPaths: string[] = [];\n\n // Find keys missing locally (exist on remote but not local)\n for (const [path, remoteBucket] of remoteMap) {\n const localBucket = localMap.get(path);\n\n if (!localBucket) {\n // Entire bucket missing locally\n missingLocal.push(...remoteBucket.keys);\n } else if (localBucket.hash !== remoteBucket.hash) {\n // Buckets differ - need deeper comparison\n differingPaths.push(path);\n\n // Find specific keys that differ\n const localKeys = new Set(localBucket.keys);\n const remoteKeys = new Set(remoteBucket.keys);\n\n for (const key of remoteKeys) {\n if (!localKeys.has(key)) {\n missingLocal.push(key);\n }\n }\n\n for (const key of localKeys) {\n if (!remoteKeys.has(key)) {\n missingRemote.push(key);\n }\n }\n }\n }\n\n // Find keys missing on remote (exist locally but not on remote)\n for (const [path, localBucket] of localMap) {\n if (!remoteMap.has(path)) {\n missingRemote.push(...localBucket.keys);\n }\n }\n\n return {\n missingLocal,\n missingRemote,\n differingPaths,\n };\n});\n\n// ============ Handler: merkle-rebuild (LWWMap) ============\n\nregisterHandler('merkle-rebuild', (payload: unknown): MerkleRebuildResult => {\n const { records, depth = 3 } = payload as MerkleRebuildPayload;\n\n // Compute hashes for each record\n const hashEntries: Array<{ key: string; hash: number }> = [];\n\n for (const record of records) {\n const itemHash = computeItemHash(\n record.key,\n record.timestamp.millis,\n record.timestamp.counter,\n record.timestamp.nodeId\n );\n hashEntries.push({ key: record.key, hash: itemHash });\n }\n\n // Build tree\n const { root, buckets } = buildMerkleTree(hashEntries, depth);\n\n return {\n rootHash: root.hash,\n buckets: Array.from(buckets.entries()),\n };\n});\n\n// ============ Handler: merkle-rebuild-ormap ============\n\nregisterHandler('merkle-rebuild-ormap', (payload: unknown): MerkleRebuildResult => {\n const { records, depth = 3 } = payload as ORMapMerkleRebuildPayload;\n\n // Compute hashes for each record\n const hashEntries: Array<{ key: string; hash: number }> = [];\n\n for (const record of records) {\n const entryHash = computeORMapEntryHash(record.key, record.tags);\n hashEntries.push({ key: record.key, hash: entryHash });\n }\n\n // Build tree\n const { root, buckets } = buildMerkleTree(hashEntries, depth);\n\n return {\n rootHash: root.hash,\n buckets: Array.from(buckets.entries()),\n };\n});\n","/**\n * Serialization Worker Script\n * SerializationWorker Implementation\n *\n * Handles CPU-intensive serialization/deserialization operations:\n * - serialize: Serialize objects to MessagePack binary format\n * - deserialize: Deserialize MessagePack binary data to objects\n *\n * Uses base64 encoding for transferring binary data through postMessage.\n */\n\nimport { registerHandler } from './base.worker';\nimport { serialize, deserialize } from '@topgunbuild/core';\nimport type {\n SerializeBatchPayload,\n SerializeBatchResult,\n DeserializeBatchPayload,\n DeserializeBatchResult,\n} from '../serialization-types';\n\n// ============ Helper Functions ============\n\n/**\n * Convert Uint8Array to base64 string for postMessage transfer\n */\nfunction uint8ArrayToBase64(bytes: Uint8Array): string {\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n/**\n * Convert base64 string back to Uint8Array\n */\nfunction base64ToUint8Array(base64: string): Uint8Array {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\n// ============ Handler: serialize ============\n\nregisterHandler('serialize', (payload: unknown): SerializeBatchResult => {\n const { items } = payload as SerializeBatchPayload;\n\n const serialized: string[] = [];\n\n for (const item of items) {\n const bytes = serialize(item);\n serialized.push(uint8ArrayToBase64(bytes));\n }\n\n return { serialized };\n});\n\n// ============ Handler: deserialize ============\n\nregisterHandler('deserialize', (payload: unknown): DeserializeBatchResult => {\n const { items } = payload as DeserializeBatchPayload;\n\n const deserialized: unknown[] = [];\n\n for (const item of items) {\n const bytes = base64ToUint8Array(item);\n deserialized.push(deserialize(bytes));\n }\n\n return { deserialized };\n});\n","/**\n * Test Worker Script\n * Used for testing WorkerPool functionality\n */\n\nimport { registerHandler } from './base.worker';\n\n// Simple echo handler\nregisterHandler('echo', (payload: unknown) => {\n return payload;\n});\n\n// Delayed echo (simulates CPU work)\nregisterHandler('delayed-echo', async (payload: unknown) => {\n const { data, delay } = payload as { data: unknown; delay: number };\n await new Promise((resolve) => setTimeout(resolve, delay));\n return data;\n});\n\n// Handler that throws an error\nregisterHandler('throw-error', (payload: unknown) => {\n const { message } = payload as { message: string };\n throw new Error(message);\n});\n\n// CPU-intensive work simulation\nregisterHandler('cpu-work', (payload: unknown) => {\n const { iterations } = payload as { iterations: number };\n let result = 0;\n for (let i = 0; i < iterations; i++) {\n result += Math.sqrt(i);\n }\n return result;\n});\n\n// Handler that returns undefined\nregisterHandler('return-undefined', () => {\n return undefined;\n});\n\n// Handler that returns null\nregisterHandler('return-null', () => {\n return null;\n});\n","/**\n * Base Worker Script\n * Worker Threads Implementation\n *\n * Main worker entry point that handles all task types.\n * Imports specialized workers to register their handlers.\n */\n\nimport { parentPort } from 'worker_threads';\n\ninterface TaskMessage {\n id: string;\n type: string;\n payload: unknown;\n}\n\ninterface TaskResponse {\n id: string;\n success: boolean;\n result?: unknown;\n error?: string;\n}\n\ntype TaskHandler = (payload: unknown) => unknown | Promise<unknown>;\n\n// Handler registry\nconst handlers = new Map<string, TaskHandler>();\n\n/**\n * Register a handler for a specific task type\n */\nexport function registerHandler(type: string, handler: TaskHandler): void {\n handlers.set(type, handler);\n}\n\n/**\n * Unregister a handler\n */\nexport function unregisterHandler(type: string): void {\n handlers.delete(type);\n}\n\n/**\n * Check if a handler is registered\n */\nexport function hasHandler(type: string): boolean {\n return handlers.has(type);\n}\n\n// Message loop\nif (parentPort) {\n parentPort.on('message', async (task: TaskMessage) => {\n const { id, type, payload } = task;\n\n const response: TaskResponse = {\n id,\n success: false,\n };\n\n try {\n const handler = handlers.get(type);\n\n if (!handler) {\n throw new Error(`Unknown task type: ${type}`);\n }\n\n const result = await handler(payload);\n response.success = true;\n response.result = result;\n } catch (error) {\n response.success = false;\n response.error =\n error instanceof Error ? error.message : String(error);\n }\n\n parentPort!.postMessage(response);\n });\n\n // Signal ready (optional, for debugging)\n // parentPort.postMessage({ type: 'ready' });\n}\n\n// Export for testing\nexport { handlers };\n\n// Load specialized workers to register their handlers\n// Using require() to ensure side effects are executed (not tree-shaken)\n// Each specialized worker calls registerHandler() when loaded\n/* eslint-disable @typescript-eslint/no-require-imports */\nrequire('./crdt.worker');\nrequire('./merkle.worker');\nrequire('./serialization.worker');\nrequire('./test.worker');\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAgCA,SAAS,kBAAkB,GAAc,GAAsB;AAC7D,MAAI,EAAE,WAAW,EAAE,QAAQ;AACzB,WAAO,EAAE,SAAS,EAAE;AAAA,EACtB;AACA,MAAI,EAAE,YAAY,EAAE,SAAS;AAC3B,WAAO,EAAE,UAAU,EAAE;AAAA,EACvB;AACA,SAAO,EAAE,OAAO,cAAc,EAAE,MAAM;AACxC;AAxCA;AAAA;AAAA;AASA;AAmCA,oBAAgB,aAAa,CAAC,YAAqC;AACjE,YAAM,EAAE,SAAS,cAAc,IAAI;AAGnC,YAAM,cAAc,oBAAI,IAIrB;AAEH,iBAAW,YAAY,eAAe;AACpC,oBAAY,IAAI,SAAS,KAAK;AAAA,UAC5B,OAAO,SAAS;AAAA,UAChB,WAAW,SAAS;AAAA,UACpB,OAAO,SAAS;AAAA,QAClB,CAAC;AAAA,MACH;AAEA,YAAM,UAAqC,CAAC;AAC5C,YAAM,YAAsB,CAAC;AAC7B,UAAI,UAAU;AAEd,iBAAW,UAAU,SAAS;AAC5B,cAAM,WAAW,YAAY,IAAI,OAAO,GAAG;AAE3C,YAAI,CAAC,UAAU;AAEb,kBAAQ,KAAK;AAAA,YACX,KAAK,OAAO;AAAA,YACZ,OAAO,OAAO;AAAA,YACd,WAAW,OAAO;AAAA,YAClB,OAAO,OAAO;AAAA,UAChB,CAAC;AAED,sBAAY,IAAI,OAAO,KAAK;AAAA,YAC1B,OAAO,OAAO;AAAA,YACd,WAAW,OAAO;AAAA,YAClB,OAAO,OAAO;AAAA,UAChB,CAAC;AACD;AAAA,QACF;AAEA,cAAM,MAAM,kBAAkB,OAAO,WAAW,SAAS,SAAS;AAGlE,cAAM,aAAa,OAAO,UAAU,WAAW,SAAS,UAAU,WAC/D,OAAO,UAAU,YAAY,SAAS,UAAU,WAChD,OAAO,UAAU,WAAW,SAAS,UAAU;AAElD,YAAI,MAAM,GAAG;AAEX,kBAAQ,KAAK;AAAA,YACX,KAAK,OAAO;AAAA,YACZ,OAAO,OAAO;AAAA,YACd,WAAW,OAAO;AAAA,YAClB,OAAO,OAAO;AAAA,UAChB,CAAC;AAED,sBAAY,IAAI,OAAO,KAAK;AAAA,YAC1B,OAAO,OAAO;AAAA,YACd,WAAW,OAAO;AAAA,YAClB,OAAO,OAAO;AAAA,UAChB,CAAC;AACD,cAAI,YAAY;AACd,sBAAU,KAAK,OAAO,GAAG;AAAA,UAC3B;AAAA,QACF,WAAW,QAAQ,GAAG;AAEpB,oBAAU,KAAK,OAAO,GAAG;AACzB;AAAA,QACF,OAAO;AAEL,cAAI,YAAY;AACd,sBAAU,KAAK,OAAO,GAAG;AAAA,UAC3B;AACA;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAID,oBAAgB,eAAe,CAAC,YAAuC;AACrE,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,IAAI;AAGJ,YAAM,SAAS,IAAI,IAAI,YAAY;AACnC,YAAM,eAAe,IAAI,IAAI,kBAAkB;AAE/C,YAAM,eAAiD,CAAC;AACxD,YAAM,oBAA8B,CAAC;AACrC,YAAM,eAAyB,CAAC;AAChC,UAAI,eAAe;AACnB,UAAI,oBAAoB;AAGxB,iBAAW,aAAa,YAAY;AAClC,YAAI,aAAa,IAAI,UAAU,GAAG,GAAG;AAEnC;AACA;AAAA,QACF;AAGA,0BAAkB,KAAK,UAAU,GAAG;AACpC,qBAAa,IAAI,UAAU,GAAG;AAG9B,YAAI,OAAO,IAAI,UAAU,GAAG,GAAG;AAC7B,uBAAa,KAAK,UAAU,GAAG;AAC/B,iBAAO,OAAO,UAAU,GAAG;AAAA,QAC7B;AAAA,MACF;AAGA,iBAAW,QAAQ,OAAO;AAExB,YAAI,aAAa,IAAI,KAAK,GAAG,GAAG;AAC9B;AACA;AAAA,QACF;AAGA,YAAI,OAAO,IAAI,KAAK,GAAG,GAAG;AAIxB;AACA;AAAA,QACF;AAGA,qBAAa,KAAK;AAAA,UAChB,KAAK,KAAK;AAAA,UACV,OAAO,KAAK;AAAA,UACZ,WAAW,KAAK;AAAA,UAChB,KAAK,KAAK;AAAA,UACV,OAAO,KAAK;AAAA,QACd,CAAC;AACD,eAAO,IAAI,KAAK,GAAG;AAAA,MACrB;AAEA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA;AAAA;;;AC5MD;AA+BA,SAAS,WAAW,KAAqB;AACvC,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,YAAQ,IAAI,WAAW,CAAC;AACxB,WAAO,KAAK,KAAK,MAAM,QAAU;AAAA,EACnC;AACA,SAAO,SAAS;AAClB;AAMA,SAAS,gBACP,KACA,QACA,SACA,QACQ;AACR,SAAO,WAAW,GAAG,GAAG,IAAI,MAAM,IAAI,OAAO,IAAI,MAAM,EAAE;AAC3D;AAMA,SAAS,sBACP,KACA,SACQ;AAER,QAAM,gBAAgB,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,IAAI,cAAc,EAAE,GAAG,CAAC;AAE5E,MAAI,cAAc;AAClB,aAAW,UAAU,eAAe;AAClC,mBAAe,IAAI,OAAO,GAAG,IAAI,OAAO,UAAU,MAAM,IAAI,OAAO,UAAU,OAAO,IAAI,OAAO,UAAU,MAAM;AAAA,EACjH;AAEA,SAAO,WAAW,WAAW;AAC/B;AAaA,SAAS,gBACP,SACA,OAC8E;AAC9E,QAAM,OAAmB,EAAE,MAAM,GAAG,UAAU,CAAC,EAAE;AACjD,QAAM,UAAU,oBAAI,IAA8C;AAElE,aAAW,EAAE,KAAK,MAAM,SAAS,KAAK,SAAS;AAC7C,UAAM,WAAW,WAAW,GAAG,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAC7D,eAAW,MAAM,KAAK,UAAU,UAAU,GAAG,KAAK;AAAA,EACpD;AAGA,iBAAe,MAAM,IAAI,OAAO,OAAO;AAEvC,SAAO,EAAE,MAAM,QAAQ;AACzB;AAEA,SAAS,WACP,MACA,KACA,UACA,UACA,OACA,OACQ;AAER,MAAI,SAAS,OAAO;AAClB,QAAI,CAAC,KAAK,QAAS,MAAK,UAAU,oBAAI,IAAI;AAC1C,SAAK,QAAQ,IAAI,KAAK,QAAQ;AAG9B,QAAIA,KAAI;AACR,eAAW,OAAO,KAAK,QAAQ,OAAO,GAAG;AACvC,MAAAA,KAAKA,KAAI,MAAO;AAAA,IAClB;AACA,SAAK,OAAOA,OAAM;AAClB,WAAO,KAAK;AAAA,EACd;AAGA,QAAM,aAAa,SAAS,KAAK;AACjC,MAAI,CAAC,KAAK,SAAU,MAAK,WAAW,CAAC;AAErC,MAAI,CAAC,KAAK,SAAS,UAAU,GAAG;AAC9B,SAAK,SAAS,UAAU,IAAI,EAAE,MAAM,EAAE;AAAA,EACxC;AAEA,aAAW,KAAK,SAAS,UAAU,GAAG,KAAK,UAAU,UAAU,QAAQ,GAAG,KAAK;AAG/E,MAAI,IAAI;AACR,aAAW,SAAS,OAAO,OAAO,KAAK,QAAQ,GAAG;AAChD,QAAK,IAAI,MAAM,OAAQ;AAAA,EACzB;AACA,OAAK,OAAO,MAAM;AAClB,SAAO,KAAK;AACd;AAEA,SAAS,eACP,MACA,MACA,OACA,SACM;AACN,MAAI,KAAK,UAAU,OAAO;AAExB,QAAI,KAAK,WAAW,KAAK,QAAQ,OAAO,GAAG;AACzC,cAAQ,IAAI,MAAM;AAAA,QAChB,MAAM,KAAK;AAAA,QACX,MAAM,MAAM,KAAK,KAAK,QAAQ,KAAK,CAAC;AAAA,MACtC,CAAC;AAAA,IACH;AACA;AAAA,EACF;AAEA,MAAI,KAAK,UAAU;AACjB,eAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,KAAK,QAAQ,GAAG;AACzD,qBAAe,OAAO,OAAO,MAAM,OAAO,OAAO;AAAA,IACnD;AAAA,EACF;AACF;AApKA;AAAA;AAAA;AAWA;AA6JA,oBAAgB,eAAe,CAAC,YAAuC;AACrE,YAAM,EAAE,SAAS,QAAQ,EAAE,IAAI;AAG/B,YAAM,cAAoD,CAAC;AAC3D,YAAM,SAAkC,CAAC;AAEzC,iBAAW,SAAS,SAAS;AAC3B,cAAM,WAAW;AAAA,UACf,MAAM;AAAA,UACN,MAAM,UAAU;AAAA,UAChB,MAAM,UAAU;AAAA,UAChB,MAAM,UAAU;AAAA,QAClB;AACA,oBAAY,KAAK,EAAE,KAAK,MAAM,KAAK,MAAM,SAAS,CAAC;AACnD,eAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC;AAAA,MACnC;AAGA,YAAM,EAAE,MAAM,QAAQ,IAAI,gBAAgB,aAAa,KAAK;AAE5D,aAAO;AAAA,QACL;AAAA,QACA,UAAU,KAAK;AAAA,QACf,SAAS,MAAM,KAAK,QAAQ,QAAQ,CAAC;AAAA,MACvC;AAAA,IACF,CAAC;AAID,oBAAgB,qBAAqB,CAAC,YAA4C;AAChF,YAAM,EAAE,SAAS,QAAQ,EAAE,IAAI;AAG/B,YAAM,cAAoD,CAAC;AAC3D,YAAM,SAAkC,CAAC;AAEzC,iBAAW,SAAS,SAAS;AAC3B,cAAM,YAAY,sBAAsB,MAAM,KAAK,MAAM,OAAO;AAChE,oBAAY,KAAK,EAAE,KAAK,MAAM,KAAK,MAAM,UAAU,CAAC;AACpD,eAAO,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC;AAAA,MACpC;AAGA,YAAM,EAAE,MAAM,QAAQ,IAAI,gBAAgB,aAAa,KAAK;AAE5D,aAAO;AAAA,QACL;AAAA,QACA,UAAU,KAAK;AAAA,QACf,SAAS,MAAM,KAAK,QAAQ,QAAQ,CAAC;AAAA,MACvC;AAAA,IACF,CAAC;AAID,oBAAgB,eAAe,CAAC,YAAuC;AACrE,YAAM,EAAE,cAAc,cAAc,IAAI;AAExC,YAAM,WAAW,IAAI,IAAwB,YAAY;AACzD,YAAM,YAAY,IAAI,IAAwB,aAAa;AAE3D,YAAM,eAAyB,CAAC;AAChC,YAAM,gBAA0B,CAAC;AACjC,YAAM,iBAA2B,CAAC;AAGlC,iBAAW,CAAC,MAAM,YAAY,KAAK,WAAW;AAC5C,cAAM,cAAc,SAAS,IAAI,IAAI;AAErC,YAAI,CAAC,aAAa;AAEhB,uBAAa,KAAK,GAAG,aAAa,IAAI;AAAA,QACxC,WAAW,YAAY,SAAS,aAAa,MAAM;AAEjD,yBAAe,KAAK,IAAI;AAGxB,gBAAM,YAAY,IAAI,IAAI,YAAY,IAAI;AAC1C,gBAAM,aAAa,IAAI,IAAI,aAAa,IAAI;AAE5C,qBAAW,OAAO,YAAY;AAC5B,gBAAI,CAAC,UAAU,IAAI,GAAG,GAAG;AACvB,2BAAa,KAAK,GAAG;AAAA,YACvB;AAAA,UACF;AAEA,qBAAW,OAAO,WAAW;AAC3B,gBAAI,CAAC,WAAW,IAAI,GAAG,GAAG;AACxB,4BAAc,KAAK,GAAG;AAAA,YACxB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAGA,iBAAW,CAAC,MAAM,WAAW,KAAK,UAAU;AAC1C,YAAI,CAAC,UAAU,IAAI,IAAI,GAAG;AACxB,wBAAc,KAAK,GAAG,YAAY,IAAI;AAAA,QACxC;AAAA,MACF;AAEA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAID,oBAAgB,kBAAkB,CAAC,YAA0C;AAC3E,YAAM,EAAE,SAAS,QAAQ,EAAE,IAAI;AAG/B,YAAM,cAAoD,CAAC;AAE3D,iBAAW,UAAU,SAAS;AAC5B,cAAM,WAAW;AAAA,UACf,OAAO;AAAA,UACP,OAAO,UAAU;AAAA,UACjB,OAAO,UAAU;AAAA,UACjB,OAAO,UAAU;AAAA,QACnB;AACA,oBAAY,KAAK,EAAE,KAAK,OAAO,KAAK,MAAM,SAAS,CAAC;AAAA,MACtD;AAGA,YAAM,EAAE,MAAM,QAAQ,IAAI,gBAAgB,aAAa,KAAK;AAE5D,aAAO;AAAA,QACL,UAAU,KAAK;AAAA,QACf,SAAS,MAAM,KAAK,QAAQ,QAAQ,CAAC;AAAA,MACvC;AAAA,IACF,CAAC;AAID,oBAAgB,wBAAwB,CAAC,YAA0C;AACjF,YAAM,EAAE,SAAS,QAAQ,EAAE,IAAI;AAG/B,YAAM,cAAoD,CAAC;AAE3D,iBAAW,UAAU,SAAS;AAC5B,cAAM,YAAY,sBAAsB,OAAO,KAAK,OAAO,IAAI;AAC/D,oBAAY,KAAK,EAAE,KAAK,OAAO,KAAK,MAAM,UAAU,CAAC;AAAA,MACvD;AAGA,YAAM,EAAE,MAAM,QAAQ,IAAI,gBAAgB,aAAa,KAAK;AAE5D,aAAO;AAAA,QACL,UAAU,KAAK;AAAA,QACf,SAAS,MAAM,KAAK,QAAQ,QAAQ,CAAC;AAAA,MACvC;AAAA,IACF,CAAC;AAAA;AAAA;;;ACnUD;AAyBA,SAAS,mBAAmB,OAA2B;AACrD,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,cAAU,OAAO,aAAa,MAAM,CAAC,CAAC;AAAA,EACxC;AACA,SAAO,KAAK,MAAM;AACpB;AAKA,SAAS,mBAAmB,QAA4B;AACtD,QAAM,SAAS,KAAK,MAAM;AAC1B,QAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AAAA,EAChC;AACA,SAAO;AACT;AA3CA,IAYA;AAZA;AAAA;AAAA;AAWA;AACA,kBAAuC;AAmCvC,oBAAgB,aAAa,CAAC,YAA2C;AACvE,YAAM,EAAE,MAAM,IAAI;AAElB,YAAM,aAAuB,CAAC;AAE9B,iBAAW,QAAQ,OAAO;AACxB,cAAM,YAAQ,uBAAU,IAAI;AAC5B,mBAAW,KAAK,mBAAmB,KAAK,CAAC;AAAA,MAC3C;AAEA,aAAO,EAAE,WAAW;AAAA,IACtB,CAAC;AAID,oBAAgB,eAAe,CAAC,YAA6C;AAC3E,YAAM,EAAE,MAAM,IAAI;AAElB,YAAM,eAA0B,CAAC;AAEjC,iBAAW,QAAQ,OAAO;AACxB,cAAM,QAAQ,mBAAmB,IAAI;AACrC,qBAAa,SAAK,yBAAY,KAAK,CAAC;AAAA,MACtC;AAEA,aAAO,EAAE,aAAa;AAAA,IACxB,CAAC;AAAA;AAAA;;;ACzED;AAAA;AAAA;AAAA;AAKA;AAGA,oBAAgB,QAAQ,CAAC,YAAqB;AAC5C,aAAO;AAAA,IACT,CAAC;AAGD,oBAAgB,gBAAgB,OAAO,YAAqB;AAC1D,YAAM,EAAE,MAAM,MAAM,IAAI;AACxB,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,KAAK,CAAC;AACzD,aAAO;AAAA,IACT,CAAC;AAGD,oBAAgB,eAAe,CAAC,YAAqB;AACnD,YAAM,EAAE,QAAQ,IAAI;AACpB,YAAM,IAAI,MAAM,OAAO;AAAA,IACzB,CAAC;AAGD,oBAAgB,YAAY,CAAC,YAAqB;AAChD,YAAM,EAAE,WAAW,IAAI;AACvB,UAAI,SAAS;AACb,eAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,kBAAU,KAAK,KAAK,CAAC;AAAA,MACvB;AACA,aAAO;AAAA,IACT,CAAC;AAGD,oBAAgB,oBAAoB,MAAM;AACxC,aAAO;AAAA,IACT,CAAC;AAGD,oBAAgB,eAAe,MAAM;AACnC,aAAO;AAAA,IACT,CAAC;AAAA;AAAA;;;AC3CD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA+BO,SAAS,gBAAgB,MAAc,SAA4B;AACxE,WAAS,IAAI,MAAM,OAAO;AAC5B;AAKO,SAAS,kBAAkB,MAAoB;AACpD,WAAS,OAAO,IAAI;AACtB;AAKO,SAAS,WAAW,MAAuB;AAChD,SAAO,SAAS,IAAI,IAAI;AAC1B;AA/CA,IAQA,uBAkBM;AA1BN;AAAA;AAQA,4BAA2B;AAkB3B,IAAM,WAAW,oBAAI,IAAyB;AAwB9C,QAAI,kCAAY;AACd,uCAAW,GAAG,WAAW,OAAO,SAAsB;AACpD,cAAM,EAAE,IAAI,MAAM,QAAQ,IAAI;AAE9B,cAAM,WAAyB;AAAA,UAC7B;AAAA,UACA,SAAS;AAAA,QACX;AAEA,YAAI;AACF,gBAAM,UAAU,SAAS,IAAI,IAAI;AAEjC,cAAI,CAAC,SAAS;AACZ,kBAAM,IAAI,MAAM,sBAAsB,IAAI,EAAE;AAAA,UAC9C;AAEA,gBAAM,SAAS,MAAM,QAAQ,OAAO;AACpC,mBAAS,UAAU;AACnB,mBAAS,SAAS;AAAA,QACpB,SAAS,OAAO;AACd,mBAAS,UAAU;AACnB,mBAAS,QACP,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QACzD;AAEA,yCAAY,YAAY,QAAQ;AAAA,MAClC,CAAC;AAAA,IAIH;AASA;AACA;AACA;AACA;AAAA;AAAA;","names":["h"]}