@kodexa-ai/document-wasm-ts 2026.2.0-develop-21765561544 → 2026.2.0-develop-21888294639
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.
- package/dist/kodexa-shared-worker.js +94 -22
- package/dist/kodexa-shared-worker.js.map +2 -2
- package/dist/kodexa.wasm +0 -0
- package/dist/worker/KodexaSharedWorker.d.ts +20 -0
- package/dist/worker/KodexaSharedWorker.d.ts.map +1 -1
- package/dist/worker/KodexaSharedWorker.js +85 -8
- package/dist/worker/KodexaSharedWorker.js.map +1 -1
- package/dist/worker/KodexaWorkerDocument.d.ts +5 -0
- package/dist/worker/KodexaWorkerDocument.d.ts.map +1 -1
- package/dist/worker/KodexaWorkerDocument.js +12 -0
- package/dist/worker/KodexaWorkerDocument.js.map +1 -1
- package/dist/worker/kodexa-shared-worker.js +116 -20
- package/dist/worker/kodexa-shared-worker.js.map +1 -1
- package/dist/worker/types.d.ts +23 -1
- package/dist/worker/types.d.ts.map +1 -1
- package/dist/worker/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -22,6 +22,14 @@ import { setSqlInstance, exposeBridgeFunctions, loadDirectOp } from '../wasm/sql
|
|
|
22
22
|
// ============================================================================
|
|
23
23
|
/** Connected ports by ID */
|
|
24
24
|
const ports = new Map();
|
|
25
|
+
/** Last heartbeat timestamp per port (for stale port detection) */
|
|
26
|
+
const lastHeartbeat = new Map();
|
|
27
|
+
/** Interval for checking stale ports */
|
|
28
|
+
let heartbeatIntervalId = null;
|
|
29
|
+
/** Ports are considered stale after this many ms without a heartbeat */
|
|
30
|
+
const STALE_PORT_THRESHOLD_MS = 60000;
|
|
31
|
+
/** How often to check for stale ports */
|
|
32
|
+
const HEARTBEAT_CHECK_INTERVAL_MS = 30000;
|
|
25
33
|
/** Counter for generating unique port IDs */
|
|
26
34
|
let nextPortId = 1;
|
|
27
35
|
/** Generate a unique port ID */
|
|
@@ -106,23 +114,62 @@ function loadSharedDocument(documentFamilyId, portId, kddbBytes) {
|
|
|
106
114
|
// Check if already loaded by another tab
|
|
107
115
|
if (sharedDocuments.has(documentFamilyId)) {
|
|
108
116
|
const existingDocRef = sharedDocuments.get(documentFamilyId);
|
|
109
|
-
//
|
|
110
|
-
let
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
117
|
+
// Validate docRef is still alive - first check tracking maps, then WASM
|
|
118
|
+
let isValid = false;
|
|
119
|
+
const docUsers = documentUsers.get(existingDocRef);
|
|
120
|
+
if (docUsers && docUsers.size > 0) {
|
|
121
|
+
// Tracking maps show active users - verify WASM doc is still valid
|
|
122
|
+
const documentGetRoot = self.documentGetRoot;
|
|
123
|
+
if (typeof documentGetRoot === 'function') {
|
|
124
|
+
try {
|
|
125
|
+
const root = documentGetRoot(existingDocRef);
|
|
126
|
+
isValid = root !== null && root !== undefined;
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
isValid = false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
// Can't validate WASM - trust tracking maps
|
|
134
|
+
isValid = true;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// If no users in tracking maps, docRef is definitely stale
|
|
138
|
+
if (!isValid) {
|
|
139
|
+
console.warn(`[shared-worker] Stale shared document ${documentFamilyId} (docRef: ${existingDocRef}), cleaning up`);
|
|
140
|
+
// Clean up all tracking for this stale entry
|
|
141
|
+
const staleUsers = sharedDocumentUsers.get(documentFamilyId);
|
|
142
|
+
if (staleUsers) {
|
|
143
|
+
for (const uid of staleUsers) {
|
|
144
|
+
unsubscribeFromDocument(existingDocRef, uid);
|
|
145
|
+
unregisterDocumentUser(existingDocRef, uid);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
sharedDocuments.delete(documentFamilyId);
|
|
149
|
+
sharedDocumentUsers.delete(documentFamilyId);
|
|
150
|
+
documentSubscriptions.delete(existingDocRef);
|
|
151
|
+
documentUsers.delete(existingDocRef);
|
|
152
|
+
// Fall through to load from bytes below
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
// Valid doc - register port as user
|
|
156
|
+
let users = sharedDocumentUsers.get(documentFamilyId);
|
|
157
|
+
if (!users) {
|
|
158
|
+
users = new Set();
|
|
159
|
+
sharedDocumentUsers.set(documentFamilyId, users);
|
|
160
|
+
}
|
|
161
|
+
users.add(portId);
|
|
162
|
+
// Also register in the regular document users tracking
|
|
163
|
+
registerDocumentUser(existingDocRef, portId);
|
|
164
|
+
// Auto-subscribe to document events
|
|
165
|
+
subscribeToDocument(existingDocRef, portId);
|
|
166
|
+
console.log(`[shared-worker] Port ${portId} joined shared document ${documentFamilyId} (docRef: ${existingDocRef}), ${users.size} users`);
|
|
167
|
+
return {
|
|
168
|
+
docRef: existingDocRef,
|
|
169
|
+
shared: true,
|
|
170
|
+
userCount: users.size,
|
|
171
|
+
};
|
|
114
172
|
}
|
|
115
|
-
users.add(portId);
|
|
116
|
-
// Also register in the regular document users tracking
|
|
117
|
-
registerDocumentUser(existingDocRef, portId);
|
|
118
|
-
// Auto-subscribe to document events
|
|
119
|
-
subscribeToDocument(existingDocRef, portId);
|
|
120
|
-
console.log(`[shared-worker] Port ${portId} joined shared document ${documentFamilyId} (docRef: ${existingDocRef}), ${users.size} users`);
|
|
121
|
-
return {
|
|
122
|
-
docRef: existingDocRef,
|
|
123
|
-
shared: true,
|
|
124
|
-
userCount: users.size,
|
|
125
|
-
};
|
|
126
173
|
}
|
|
127
174
|
// Not loaded - need kddbBytes
|
|
128
175
|
if (!kddbBytes) {
|
|
@@ -318,8 +365,34 @@ function cleanupPort(portId) {
|
|
|
318
365
|
documentUsers.delete(docRef);
|
|
319
366
|
}
|
|
320
367
|
}
|
|
368
|
+
// Remove heartbeat tracking
|
|
369
|
+
lastHeartbeat.delete(portId);
|
|
321
370
|
// Remove port
|
|
322
371
|
ports.delete(portId);
|
|
372
|
+
// Stop heartbeat checking if no ports remain
|
|
373
|
+
if (ports.size === 0 && heartbeatIntervalId) {
|
|
374
|
+
clearInterval(heartbeatIntervalId);
|
|
375
|
+
heartbeatIntervalId = null;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Check for and clean up stale ports that haven't sent a heartbeat recently.
|
|
380
|
+
* This catches tab crashes, mobile eviction, and other cases where
|
|
381
|
+
* beforeunload doesn't fire.
|
|
382
|
+
*/
|
|
383
|
+
function checkForStalePorts() {
|
|
384
|
+
const now = Date.now();
|
|
385
|
+
// Collect stale ports first to avoid modifying map during iteration
|
|
386
|
+
const stalePorts = [];
|
|
387
|
+
for (const [portId, lastBeat] of lastHeartbeat) {
|
|
388
|
+
if (now - lastBeat >= STALE_PORT_THRESHOLD_MS) {
|
|
389
|
+
stalePorts.push(portId);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
for (const portId of stalePorts) {
|
|
393
|
+
console.log(`[shared-worker] Port ${portId} stale (no heartbeat for ${STALE_PORT_THRESHOLD_MS}ms), cleaning up`);
|
|
394
|
+
cleanupPort(portId); // cleanupPort already removes from lastHeartbeat
|
|
395
|
+
}
|
|
323
396
|
}
|
|
324
397
|
// ============================================================================
|
|
325
398
|
// Event Broadcasting
|
|
@@ -628,22 +701,24 @@ function handlePortMessage(portId, port, event) {
|
|
|
628
701
|
}
|
|
629
702
|
// Handle shared document messages
|
|
630
703
|
if ('type' in data && data.type === 'loadSharedDocument') {
|
|
704
|
+
const { documentFamilyId, kddbBytes, requestId } = data;
|
|
631
705
|
if (!initialized) {
|
|
632
706
|
port.postMessage({
|
|
633
707
|
type: 'sharedDocumentResponse',
|
|
634
708
|
success: false,
|
|
635
709
|
error: 'Worker not initialized',
|
|
636
710
|
requestType: 'loadSharedDocument',
|
|
711
|
+
requestId,
|
|
637
712
|
});
|
|
638
713
|
return;
|
|
639
714
|
}
|
|
640
715
|
try {
|
|
641
|
-
const { documentFamilyId, kddbBytes } = data;
|
|
642
716
|
const result = loadSharedDocument(documentFamilyId, portId, kddbBytes);
|
|
643
717
|
port.postMessage({
|
|
644
718
|
type: 'sharedDocumentResponse',
|
|
645
719
|
success: true,
|
|
646
720
|
requestType: 'loadSharedDocument',
|
|
721
|
+
requestId,
|
|
647
722
|
...result,
|
|
648
723
|
});
|
|
649
724
|
}
|
|
@@ -653,18 +728,20 @@ function handlePortMessage(portId, port, event) {
|
|
|
653
728
|
success: false,
|
|
654
729
|
error: error instanceof Error ? error.message : String(error),
|
|
655
730
|
requestType: 'loadSharedDocument',
|
|
731
|
+
requestId,
|
|
656
732
|
});
|
|
657
733
|
}
|
|
658
734
|
return;
|
|
659
735
|
}
|
|
660
736
|
if ('type' in data && data.type === 'releaseSharedDocument') {
|
|
737
|
+
const { documentFamilyId, requestId } = data;
|
|
661
738
|
try {
|
|
662
|
-
const { documentFamilyId } = data;
|
|
663
739
|
const result = releaseSharedDocument(documentFamilyId, portId);
|
|
664
740
|
port.postMessage({
|
|
665
741
|
type: 'sharedDocumentResponse',
|
|
666
742
|
success: true,
|
|
667
743
|
requestType: 'releaseSharedDocument',
|
|
744
|
+
requestId,
|
|
668
745
|
...result,
|
|
669
746
|
});
|
|
670
747
|
}
|
|
@@ -674,33 +751,47 @@ function handlePortMessage(portId, port, event) {
|
|
|
674
751
|
success: false,
|
|
675
752
|
error: error instanceof Error ? error.message : String(error),
|
|
676
753
|
requestType: 'releaseSharedDocument',
|
|
754
|
+
requestId,
|
|
677
755
|
});
|
|
678
756
|
}
|
|
679
757
|
return;
|
|
680
758
|
}
|
|
681
759
|
if ('type' in data && data.type === 'isDocumentShared') {
|
|
682
|
-
const { documentFamilyId } = data;
|
|
760
|
+
const { documentFamilyId, requestId } = data;
|
|
683
761
|
const shared = isDocumentShared(documentFamilyId);
|
|
684
762
|
const docRef = getSharedDocumentRef(documentFamilyId);
|
|
685
763
|
port.postMessage({
|
|
686
764
|
type: 'sharedDocumentResponse',
|
|
687
765
|
success: true,
|
|
688
766
|
requestType: 'isDocumentShared',
|
|
767
|
+
requestId,
|
|
689
768
|
shared,
|
|
690
769
|
docRef,
|
|
691
770
|
});
|
|
692
771
|
return;
|
|
693
772
|
}
|
|
694
773
|
if ('type' in data && data.type === 'invalidateSharedDocument') {
|
|
695
|
-
const { documentFamilyId, reason } = data;
|
|
774
|
+
const { documentFamilyId, reason, requestId } = data;
|
|
696
775
|
invalidateSharedDocument(documentFamilyId, portId, reason || 'reload');
|
|
697
776
|
port.postMessage({
|
|
698
777
|
type: 'sharedDocumentResponse',
|
|
699
778
|
success: true,
|
|
700
779
|
requestType: 'invalidateSharedDocument',
|
|
780
|
+
requestId,
|
|
701
781
|
});
|
|
702
782
|
return;
|
|
703
783
|
}
|
|
784
|
+
// Handle heartbeat message
|
|
785
|
+
if ('type' in data && data.type === 'heartbeat') {
|
|
786
|
+
lastHeartbeat.set(portId, Date.now());
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
789
|
+
// Handle disconnect message (clean exit from tab close/reload)
|
|
790
|
+
if ('type' in data && data.type === 'disconnect') {
|
|
791
|
+
console.log(`[shared-worker] Port ${portId} sent disconnect message, cleaning up`);
|
|
792
|
+
cleanupPort(portId);
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
704
795
|
// Handle RPC call
|
|
705
796
|
if ('type' in data && data.type === 'call') {
|
|
706
797
|
if (!initialized) {
|
|
@@ -727,6 +818,7 @@ self.onconnect = (event) => {
|
|
|
727
818
|
const portId = generatePortId();
|
|
728
819
|
console.log(`[shared-worker] New port connected: ${portId}`);
|
|
729
820
|
ports.set(portId, port);
|
|
821
|
+
lastHeartbeat.set(portId, Date.now());
|
|
730
822
|
// Set up message handler for this port
|
|
731
823
|
port.onmessage = (e) => handlePortMessage(portId, port, e);
|
|
732
824
|
// Handle port closure (tab closed)
|
|
@@ -737,6 +829,10 @@ self.onconnect = (event) => {
|
|
|
737
829
|
};
|
|
738
830
|
// Start the port
|
|
739
831
|
port.start();
|
|
832
|
+
// Start heartbeat checking interval if not already running
|
|
833
|
+
if (!heartbeatIntervalId) {
|
|
834
|
+
heartbeatIntervalId = setInterval(checkForStalePorts, HEARTBEAT_CHECK_INTERVAL_MS);
|
|
835
|
+
}
|
|
740
836
|
// If already initialized, send ready immediately
|
|
741
837
|
if (initialized) {
|
|
742
838
|
const readyMessage = { type: 'ready', portId };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kodexa-shared-worker.js","sourceRoot":"","sources":["../../src/worker/kodexa-shared-worker.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Kodexa SharedWorker Entry Point\n *\n * This SharedWorker owns the Go WASM instance and exposes an RPC-style API\n * via MessagePort. Multiple tabs/windows can connect and share the same\n * WASM instance and documents, with events broadcast to all interested ports.\n *\n * Key differences from dedicated worker:\n * - Uses onconnect to handle multiple port connections\n * - Tracks document subscriptions per port for event broadcasting\n * - Reference counts documents to know when to clean up\n *\n * Initialization order (critical):\n * 1. sql.js WASM loaded and bridge exposed to globalThis\n * 2. wasm_exec.js loaded (defines globalThis.Go)\n * 3. kodexa.wasm instantiated and Go runtime started\n * 4. Worker signals 'ready' to each connected port\n */\n\n/// <reference lib=\"webworker\" />\n\nimport type {\n WorkerConfig,\n WorkerErrorMessage,\n WorkerWasmEventMessage,\n SharedWorkerRequest,\n SharedWorkerResponse,\n SharedWorkerReadyMessage,\n SharedWorkerInboundMessage,\n} from './types';\nimport { setSqlInstance, exposeBridgeFunctions, loadDirectOp } from '../wasm/sqljs-core';\n\ndeclare const self: SharedWorkerGlobalScope;\n\n// ============================================================================\n// Port Management\n// ============================================================================\n\n/** Connected ports by ID */\nconst ports = new Map<string, MessagePort>();\n\n/** Counter for generating unique port IDs */\nlet nextPortId = 1;\n\n/** Generate a unique port ID */\nfunction generatePortId(): string {\n return `port_${nextPortId++}_${Date.now()}`;\n}\n\n// ============================================================================\n// Document State Management\n// ============================================================================\n\n/** Track which ports are subscribed to which documents for event broadcasting */\nconst documentSubscriptions = new Map<number, Set<string>>(); // docRef -> Set<portId>\n\n/** Track which ports are using which documents (for cleanup) */\nconst documentUsers = new Map<number, Set<string>>(); // docRef -> Set<portId>\n\n// ============================================================================\n// Shared Document Registry (by documentFamilyId)\n// Enables multiple tabs to share the same WASM document instance\n// ============================================================================\n\n/** Map documentFamilyId -> docRef for sharing documents across tabs */\nconst sharedDocuments = new Map<string, number>();\n\n/** Track which ports are using each shared document (by documentFamilyId) */\nconst sharedDocumentUsers = new Map<string, Set<string>>(); // documentFamilyId -> Set<portId>\n\n/**\n * Subscribe a port to document events.\n */\nfunction subscribeToDocument(docRef: number, portId: string): void {\n if (!documentSubscriptions.has(docRef)) {\n documentSubscriptions.set(docRef, new Set());\n }\n documentSubscriptions.get(docRef)!.add(portId);\n console.log(`[shared-worker] Port ${portId} subscribed to document ${docRef}`);\n}\n\n/**\n * Unsubscribe a port from document events.\n */\nfunction unsubscribeFromDocument(docRef: number, portId: string): void {\n const subscribers = documentSubscriptions.get(docRef);\n if (subscribers) {\n subscribers.delete(portId);\n if (subscribers.size === 0) {\n documentSubscriptions.delete(docRef);\n }\n console.log(`[shared-worker] Port ${portId} unsubscribed from document ${docRef}`);\n }\n}\n\n/**\n * Register a port as using a document (for reference counting).\n */\nfunction registerDocumentUser(docRef: number, portId: string): void {\n if (!documentUsers.has(docRef)) {\n documentUsers.set(docRef, new Set());\n }\n documentUsers.get(docRef)!.add(portId);\n}\n\n/**\n * Unregister a port from a document. Returns true if document should be freed.\n */\nfunction unregisterDocumentUser(docRef: number, portId: string): boolean {\n const users = documentUsers.get(docRef);\n if (users) {\n users.delete(portId);\n if (users.size === 0) {\n documentUsers.delete(docRef);\n return true; // No more users, safe to free\n }\n }\n return false;\n}\n\n// ============================================================================\n// Shared Document Functions (by documentFamilyId)\n// ============================================================================\n\n/**\n * Load or join a shared document by documentFamilyId.\n * If another tab has already loaded this document, returns the existing docRef.\n * If not loaded, loads from provided kddbBytes and registers as shared.\n *\n * @param documentFamilyId - Unique identifier for the document family\n * @param portId - Port ID of the requesting tab\n * @param kddbBytes - KDDB bytes (required if document not already loaded)\n * @returns Object with docRef, shared status, and user count\n */\nfunction loadSharedDocument(\n documentFamilyId: string,\n portId: string,\n kddbBytes?: Uint8Array\n): { docRef: number; shared: boolean; userCount: number } {\n // Check if already loaded by another tab\n if (sharedDocuments.has(documentFamilyId)) {\n const existingDocRef = sharedDocuments.get(documentFamilyId)!;\n\n // Register this port as a user\n let users = sharedDocumentUsers.get(documentFamilyId);\n if (!users) {\n users = new Set();\n sharedDocumentUsers.set(documentFamilyId, users);\n }\n users.add(portId);\n\n // Also register in the regular document users tracking\n registerDocumentUser(existingDocRef, portId);\n\n // Auto-subscribe to document events\n subscribeToDocument(existingDocRef, portId);\n\n console.log(`[shared-worker] Port ${portId} joined shared document ${documentFamilyId} (docRef: ${existingDocRef}), ${users.size} users`);\n\n return {\n docRef: existingDocRef,\n shared: true,\n userCount: users.size,\n };\n }\n\n // Not loaded - need kddbBytes\n if (!kddbBytes) {\n throw new Error(`Document ${documentFamilyId} not loaded and no bytes provided`);\n }\n\n // Load new document using loadDocument\n const loadDocument = (self as any).loadDocument;\n if (typeof loadDocument !== 'function') {\n throw new Error('loadDocument function not available');\n }\n\n const docRef = loadDocument(kddbBytes);\n if (docRef === 0) {\n throw new Error('Failed to load document from KDDB bytes');\n }\n\n // Register as shared document\n sharedDocuments.set(documentFamilyId, docRef);\n const users = new Set<string>([portId]);\n sharedDocumentUsers.set(documentFamilyId, users);\n\n // Register in regular tracking\n registerDocumentUser(docRef, portId);\n\n // Auto-subscribe to events\n subscribeToDocument(docRef, portId);\n\n console.log(`[shared-worker] Port ${portId} loaded shared document ${documentFamilyId} (docRef: ${docRef})`);\n\n return {\n docRef,\n shared: false,\n userCount: 1,\n };\n}\n\n/**\n * Release this tab's reference to a shared document.\n * Document is freed when all tabs release it.\n *\n * @param documentFamilyId - Document family ID to release\n * @param portId - Port ID releasing the document\n * @returns Object with freed status and remaining user count\n */\nfunction releaseSharedDocument(\n documentFamilyId: string,\n portId: string\n): { freed: boolean; remainingUsers?: number; notFound?: boolean } {\n const docRef = sharedDocuments.get(documentFamilyId);\n\n if (docRef === undefined) {\n return { freed: false, notFound: true };\n }\n\n // Remove this port from shared document users\n const users = sharedDocumentUsers.get(documentFamilyId);\n if (users) {\n users.delete(portId);\n\n // Unsubscribe from events\n unsubscribeFromDocument(docRef, portId);\n\n // Unregister from regular tracking\n unregisterDocumentUser(docRef, portId);\n\n // If no users left, free the document\n if (users.size === 0) {\n console.log(`[shared-worker] Freeing shared document ${documentFamilyId} (docRef: ${docRef}) - no more users`);\n\n // Free the document\n try {\n const freeDocument = (self as any).freeDocument;\n if (typeof freeDocument === 'function') {\n freeDocument(docRef);\n }\n } catch (error) {\n console.error(`[shared-worker] Error freeing document ${docRef}:`, error);\n }\n\n // Clean up registry\n sharedDocuments.delete(documentFamilyId);\n sharedDocumentUsers.delete(documentFamilyId);\n documentSubscriptions.delete(docRef);\n\n return { freed: true };\n }\n\n console.log(`[shared-worker] Port ${portId} released shared document ${documentFamilyId}, ${users.size} users remaining`);\n return { freed: false, remainingUsers: users.size };\n }\n\n return { freed: false, notFound: true };\n}\n\n/**\n * Check if a document is already loaded as a shared document.\n *\n * @param documentFamilyId - Document family ID to check\n * @returns true if document is loaded, false otherwise\n */\nfunction isDocumentShared(documentFamilyId: string): boolean {\n return sharedDocuments.has(documentFamilyId);\n}\n\n/**\n * Get the docRef for a shared document by documentFamilyId.\n *\n * @param documentFamilyId - Document family ID to look up\n * @returns docRef if found, undefined otherwise\n */\nfunction getSharedDocumentRef(documentFamilyId: string): number | undefined {\n return sharedDocuments.get(documentFamilyId);\n}\n\n/**\n * Invalidate a shared document and notify other tabs.\n * Called when one tab force-reloads a document.\n *\n * @param documentFamilyId - Document family ID being invalidated\n * @param portId - Port ID of the tab initiating the invalidation\n * @param reason - Reason for invalidation (e.g., 'reload', 'server-update')\n */\nfunction invalidateSharedDocument(\n documentFamilyId: string,\n portId: string,\n reason: string\n): void {\n const docRef = sharedDocuments.get(documentFamilyId);\n\n if (docRef === undefined) {\n return;\n }\n\n const users = sharedDocumentUsers.get(documentFamilyId);\n if (!users) {\n return;\n }\n\n // Notify all OTHER tabs using this document\n for (const userPortId of users) {\n if (userPortId !== portId) {\n const port = ports.get(userPortId);\n if (port) {\n try {\n port.postMessage({\n type: 'documentInvalidated',\n documentFamilyId,\n reason,\n initiatorPortId: portId,\n });\n console.log(`[shared-worker] Notified port ${userPortId} of document invalidation: ${documentFamilyId}`);\n } catch (error) {\n console.error(`[shared-worker] Error notifying port ${userPortId}:`, error);\n }\n }\n }\n }\n}\n\n/**\n * Cleanup all resources associated with a port.\n */\nfunction cleanupPort(portId: string): void {\n console.log(`[shared-worker] Cleaning up port ${portId}`);\n\n // Remove from all document subscriptions\n for (const [docRef, subscribers] of documentSubscriptions) {\n subscribers.delete(portId);\n if (subscribers.size === 0) {\n documentSubscriptions.delete(docRef);\n }\n }\n\n // Release all shared documents this port was using\n for (const [documentFamilyId, users] of sharedDocumentUsers) {\n if (users.has(portId)) {\n users.delete(portId);\n\n // If last user, free document and clean up\n if (users.size === 0) {\n const docRef = sharedDocuments.get(documentFamilyId);\n if (docRef !== undefined) {\n console.log(`[shared-worker] Freeing shared document ${documentFamilyId} (docRef: ${docRef}) - port ${portId} was last user`);\n try {\n const freeDocument = (self as any).freeDocument;\n if (typeof freeDocument === 'function') {\n freeDocument(docRef);\n }\n } catch (error) {\n console.error(`[shared-worker] Error freeing document ${docRef}:`, error);\n }\n sharedDocuments.delete(documentFamilyId);\n documentUsers.delete(docRef);\n }\n sharedDocumentUsers.delete(documentFamilyId);\n }\n }\n }\n\n // Unregister from all non-shared document users\n for (const [docRef, users] of documentUsers) {\n users.delete(portId);\n if (users.size === 0) {\n // Check if this is a shared document - if so, it's already handled above\n let isShared = false;\n for (const [, sharedDocRef] of sharedDocuments) {\n if (sharedDocRef === docRef) {\n isShared = true;\n break;\n }\n }\n\n if (!isShared) {\n // No ports using this non-shared document, free it\n console.log(`[shared-worker] Freeing non-shared document ${docRef} - no more users`);\n try {\n const freeDocument = (self as any).freeDocument;\n if (typeof freeDocument === 'function') {\n freeDocument(docRef);\n }\n } catch (error) {\n console.error(`[shared-worker] Error freeing document ${docRef}:`, error);\n }\n }\n documentUsers.delete(docRef);\n }\n }\n\n // Remove port\n ports.delete(portId);\n}\n\n// ============================================================================\n// Event Broadcasting\n// ============================================================================\n\n/**\n * Broadcast an event to all ports subscribed to a document.\n */\nfunction broadcastToSubscribers(docRef: number, eventType: string, detail: unknown): void {\n const subscribers = documentSubscriptions.get(docRef);\n console.log(`[shared-worker] broadcastToSubscribers called docRef=${docRef} eventType=${eventType} subscriberCount=${subscribers?.size ?? 0}`);\n if (!subscribers || subscribers.size === 0) {\n console.log(`[shared-worker] No subscribers for document ${docRef}, event not broadcast`);\n return;\n }\n\n const message: WorkerWasmEventMessage = {\n type: 'wasmEvent',\n eventType,\n detail,\n documentRef: docRef,\n };\n\n for (const portId of subscribers) {\n const port = ports.get(portId);\n if (port) {\n try {\n console.log(`[shared-worker] Posting wasmEvent to port ${portId}`);\n port.postMessage(message);\n console.log(`[shared-worker] Posted wasmEvent to port ${portId} successfully`);\n } catch (error) {\n console.error(`[shared-worker] Error posting to port ${portId}:`, error);\n }\n } else {\n console.warn(`[shared-worker] Port ${portId} not found in ports map, cannot send event`);\n }\n }\n}\n\n/**\n * Broadcast an event to ALL connected ports.\n */\nfunction broadcastToAll(message: unknown): void {\n for (const [portId, port] of ports) {\n try {\n port.postMessage(message);\n } catch (error) {\n console.error(`[shared-worker] Error posting to port ${portId}:`, error);\n }\n }\n}\n\n// ============================================================================\n// Worker State\n// ============================================================================\n\nlet initialized = false;\nlet initPromise: Promise<void> | null = null;\nlet config: WorkerConfig = {};\n\n// ============================================================================\n// Event Forwarding from WASM\n// ============================================================================\n\n/**\n * Set up event forwarding from WASM to connected ports.\n *\n * SIMPLIFIED ARCHITECTURE:\n * Go WASM calls document.dispatchEvent(CustomEvent) with JSON string detail.\n * We parse the JSON once here and broadcast directly to subscribers.\n * No intermediate self.dispatchEvent → addEventListener dance needed.\n */\nfunction setupEventForwarding(): void {\n // Create a document shim for Go WASM to dispatch events\n const documentShim = {\n addEventListener: (type: string, handler: EventListener) => {\n // Go WASM may register listeners, but we handle events directly in dispatchEvent\n console.log(`[shared-worker] Event listener registered for: ${type} (handled in dispatchEvent)`);\n },\n removeEventListener: (type: string, handler: EventListener) => {\n // No-op - we don't use addEventListener\n },\n dispatchEvent: (event: Event) => {\n // Handle CustomEvents from Go WASM directly - no intermediate dispatch needed\n if (!(event instanceof CustomEvent)) {\n return true;\n }\n\n const eventType = event.type;\n const rawDetail = event.detail;\n\n // Parse JSON detail once (Go sends it as a JSON string)\n let parsedDetail: any;\n try {\n parsedDetail = typeof rawDetail === 'string' ? JSON.parse(rawDetail) : rawDetail;\n } catch (e) {\n console.warn(`[shared-worker] Failed to parse ${eventType} detail:`, e);\n parsedDetail = rawDetail;\n }\n\n const docRef = parsedDetail?.documentRef;\n console.log(`[shared-worker] dispatchEvent: ${eventType}`, { docRef, eventType: parsedDetail?.eventType });\n\n if (docRef !== undefined) {\n // Document-specific event - broadcast to subscribers only\n // Pass the PARSED detail so UI doesn't need to parse again\n broadcastToSubscribers(docRef, eventType, parsedDetail);\n } else {\n // Global event - broadcast to all ports\n broadcastToAll({\n type: 'wasmEvent',\n eventType: eventType,\n detail: parsedDetail,\n } as WorkerWasmEventMessage);\n }\n\n return true;\n },\n createElement: () => null,\n body: null,\n documentElement: null,\n };\n\n (self as any).document = documentShim;\n\n console.log('[shared-worker] Event forwarding configured (simplified architecture)');\n}\n\n// ============================================================================\n// WASM Loading (same as dedicated worker)\n// ============================================================================\n\nasync function initializeSqlJs(): Promise<void> {\n const sqlJsUrl = 'https://sql.js.org/dist/sql-wasm.js';\n const sqlWasmUrl = 'https://sql.js.org/dist/sql-wasm.wasm';\n\n try {\n const response = await fetch(sqlJsUrl);\n if (!response.ok) {\n throw new Error(`Failed to fetch sql-wasm.js: ${response.statusText}`);\n }\n const code = await response.text();\n\n const wrappedCode = `\n (function(module, exports) {\n ${code}\n return module.exports;\n })\n `;\n\n // eslint-disable-next-line no-eval\n const moduleFactory = eval(wrappedCode);\n const mockModule = { exports: {} as any };\n const initSqlJs = moduleFactory(mockModule, mockModule.exports);\n\n if (typeof initSqlJs !== 'function') {\n throw new Error('initSqlJs not found after loading sql-wasm.js');\n }\n\n const sqlConfig = {\n locateFile: () => sqlWasmUrl,\n };\n\n const SQL = await initSqlJs(sqlConfig);\n setSqlInstance(SQL);\n exposeBridgeFunctions();\n\n // Expose loadDocument function\n (self as any).loadDocument = (bytes: Uint8Array): number => {\n const handle = loadDirectOp(bytes);\n if (handle === 0) {\n console.error('[shared-worker] Failed to load database');\n return 0;\n }\n return (self as any).createDocumentFromHandle(handle);\n };\n\n console.log('[shared-worker] sql.js initialized from official CDN');\n } catch (error) {\n console.error('[shared-worker] Failed to initialize sql.js:', error);\n throw new Error(`Failed to initialize sql.js: ${error}`);\n }\n}\n\nasync function loadWasmExec(): Promise<void> {\n if ((self as any).Go) {\n return;\n }\n\n const baseUrl = config.wasmBaseUrl || self.location.origin;\n const wasmExecUrl = `${baseUrl}/wasm_exec.js`;\n\n try {\n const response = await fetch(wasmExecUrl);\n if (!response.ok) {\n throw new Error(`Failed to fetch wasm_exec.js: ${response.statusText}`);\n }\n const code = await response.text();\n // eslint-disable-next-line no-eval\n eval(code);\n console.log('[shared-worker] wasm_exec.js loaded');\n } catch (error) {\n throw new Error(`Failed to load wasm_exec.js: ${error}`);\n }\n}\n\nasync function loadGoWasm(): Promise<void> {\n const baseUrl = config.wasmBaseUrl || self.location.origin;\n // Add cache-busting version if provided\n const versionParam = config.wasmVersion ? `?v=${config.wasmVersion}` : '';\n const wasmUrl = `${baseUrl}/kodexa.wasm${versionParam}`;\n\n const response = await fetch(wasmUrl);\n if (!response.ok) {\n throw new Error(`Failed to fetch kodexa.wasm: ${response.statusText}`);\n }\n const wasmBytes = await response.arrayBuffer();\n\n const go = new (self as any).Go();\n const result = await WebAssembly.instantiate(wasmBytes, go.importObject);\n go.run(result.instance);\n\n const logLevel = config.logLevel || 'warn';\n if ((self as any).kodexa_setLogLevel) {\n (self as any).kodexa_setLogLevel(logLevel);\n }\n\n console.log('[shared-worker] Go WASM loaded');\n}\n\nasync function initialize(workerConfig?: WorkerConfig): Promise<void> {\n if (initialized) {\n return;\n }\n\n if (initPromise) {\n return initPromise;\n }\n\n config = workerConfig || {};\n\n initPromise = (async () => {\n try {\n setupEventForwarding();\n await initializeSqlJs();\n await loadWasmExec();\n await loadGoWasm();\n initialized = true;\n console.log('[shared-worker] Kodexa WASM fully initialized');\n } catch (error) {\n console.error('[shared-worker] Initialization failed:', error);\n throw error;\n }\n })();\n\n return initPromise;\n}\n\n// ============================================================================\n// Message Handling\n// ============================================================================\n\n/**\n * Handle RPC call from a port.\n */\nfunction handleCall(request: SharedWorkerRequest): SharedWorkerResponse {\n const { id, method, args, portId } = request;\n\n try {\n const fn = (self as any)[method];\n if (typeof fn !== 'function') {\n return {\n id,\n portId,\n success: false,\n error: `Function '${method}' not found on globalThis`,\n };\n }\n\n const result = fn(...(args || []));\n\n // Track document usage when creating/loading documents\n if (method === 'createDocument' || method === 'createDocumentFromText' ||\n method === 'createDocumentFromJson' || method === 'createDocumentFromKddbBytes' ||\n method === 'loadDocument') {\n if (typeof result === 'number' && result > 0) {\n registerDocumentUser(result, portId);\n }\n }\n\n // Track document disposal\n if (method === 'freeDocument' && args && args.length > 0) {\n const docRef = args[0] as number;\n const shouldFree = unregisterDocumentUser(docRef, portId);\n if (!shouldFree) {\n // Other ports still using this document, don't actually free it\n return { id, portId, success: true, result: undefined };\n }\n }\n\n return { id, portId, success: true, result };\n } catch (error) {\n return {\n id,\n portId,\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n/**\n * Handle messages from a connected port.\n */\nfunction handlePortMessage(portId: string, port: MessagePort, event: MessageEvent<SharedWorkerInboundMessage>): void {\n const data = event.data;\n\n // Handle init message\n if ('type' in data && data.type === 'init') {\n (async () => {\n try {\n await initialize(data.config);\n const readyMessage: SharedWorkerReadyMessage = { type: 'ready', portId };\n port.postMessage(readyMessage);\n } catch (error) {\n const errorMessage: WorkerErrorMessage = {\n type: 'error',\n error: error instanceof Error ? error.message : String(error),\n };\n port.postMessage(errorMessage);\n }\n })();\n return;\n }\n\n // Handle subscription messages\n if ('type' in data && data.type === 'subscribe') {\n subscribeToDocument(data.docRef, portId);\n return;\n }\n\n if ('type' in data && data.type === 'unsubscribe') {\n unsubscribeFromDocument(data.docRef, portId);\n return;\n }\n\n // Handle shared document messages\n if ('type' in data && data.type === 'loadSharedDocument') {\n if (!initialized) {\n port.postMessage({\n type: 'sharedDocumentResponse',\n success: false,\n error: 'Worker not initialized',\n requestType: 'loadSharedDocument',\n });\n return;\n }\n\n try {\n const { documentFamilyId, kddbBytes } = data as any;\n const result = loadSharedDocument(documentFamilyId, portId, kddbBytes);\n port.postMessage({\n type: 'sharedDocumentResponse',\n success: true,\n requestType: 'loadSharedDocument',\n ...result,\n });\n } catch (error) {\n port.postMessage({\n type: 'sharedDocumentResponse',\n success: false,\n error: error instanceof Error ? error.message : String(error),\n requestType: 'loadSharedDocument',\n });\n }\n return;\n }\n\n if ('type' in data && data.type === 'releaseSharedDocument') {\n try {\n const { documentFamilyId } = data as any;\n const result = releaseSharedDocument(documentFamilyId, portId);\n port.postMessage({\n type: 'sharedDocumentResponse',\n success: true,\n requestType: 'releaseSharedDocument',\n ...result,\n });\n } catch (error) {\n port.postMessage({\n type: 'sharedDocumentResponse',\n success: false,\n error: error instanceof Error ? error.message : String(error),\n requestType: 'releaseSharedDocument',\n });\n }\n return;\n }\n\n if ('type' in data && data.type === 'isDocumentShared') {\n const { documentFamilyId } = data as any;\n const shared = isDocumentShared(documentFamilyId);\n const docRef = getSharedDocumentRef(documentFamilyId);\n port.postMessage({\n type: 'sharedDocumentResponse',\n success: true,\n requestType: 'isDocumentShared',\n shared,\n docRef,\n });\n return;\n }\n\n if ('type' in data && data.type === 'invalidateSharedDocument') {\n const { documentFamilyId, reason } = data as any;\n invalidateSharedDocument(documentFamilyId, portId, reason || 'reload');\n port.postMessage({\n type: 'sharedDocumentResponse',\n success: true,\n requestType: 'invalidateSharedDocument',\n });\n return;\n }\n\n // Handle RPC call\n if ('type' in data && data.type === 'call') {\n if (!initialized) {\n const response: SharedWorkerResponse = {\n id: (data as SharedWorkerRequest).id,\n portId,\n success: false,\n error: 'Worker not initialized. Send init message first.',\n };\n port.postMessage(response);\n return;\n }\n\n // Add portId to the request\n const request = { ...data, portId } as SharedWorkerRequest;\n const response = handleCall(request);\n port.postMessage(response);\n }\n}\n\n// ============================================================================\n// SharedWorker Connection Handler\n// ============================================================================\n\nself.onconnect = (event: MessageEvent) => {\n const port = event.ports[0];\n const portId = generatePortId();\n\n console.log(`[shared-worker] New port connected: ${portId}`);\n ports.set(portId, port);\n\n // Set up message handler for this port\n port.onmessage = (e) => handlePortMessage(portId, port, e);\n\n // Handle port closure (tab closed)\n // Note: Not all browsers reliably fire this event\n port.onmessageerror = () => {\n console.log(`[shared-worker] Port ${portId} message error, cleaning up`);\n cleanupPort(portId);\n };\n\n // Start the port\n port.start();\n\n // If already initialized, send ready immediately\n if (initialized) {\n const readyMessage: SharedWorkerReadyMessage = { type: 'ready', portId };\n port.postMessage(readyMessage);\n }\n\n // Send connected message so port knows its ID\n port.postMessage({ type: 'connected', portId });\n};\n\n// Log that shared worker is ready for connections\nconsole.log('[shared-worker] Kodexa SharedWorker ready for connections');\n"]}
|
|
1
|
+
{"version":3,"file":"kodexa-shared-worker.js","sourceRoot":"","sources":["../../src/worker/kodexa-shared-worker.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Kodexa SharedWorker Entry Point\n *\n * This SharedWorker owns the Go WASM instance and exposes an RPC-style API\n * via MessagePort. Multiple tabs/windows can connect and share the same\n * WASM instance and documents, with events broadcast to all interested ports.\n *\n * Key differences from dedicated worker:\n * - Uses onconnect to handle multiple port connections\n * - Tracks document subscriptions per port for event broadcasting\n * - Reference counts documents to know when to clean up\n *\n * Initialization order (critical):\n * 1. sql.js WASM loaded and bridge exposed to globalThis\n * 2. wasm_exec.js loaded (defines globalThis.Go)\n * 3. kodexa.wasm instantiated and Go runtime started\n * 4. Worker signals 'ready' to each connected port\n */\n\n/// <reference lib=\"webworker\" />\n\nimport type {\n WorkerConfig,\n WorkerErrorMessage,\n WorkerWasmEventMessage,\n SharedWorkerRequest,\n SharedWorkerResponse,\n SharedWorkerReadyMessage,\n SharedWorkerInboundMessage,\n} from './types';\nimport { setSqlInstance, exposeBridgeFunctions, loadDirectOp } from '../wasm/sqljs-core';\n\ndeclare const self: SharedWorkerGlobalScope;\n\n// ============================================================================\n// Port Management\n// ============================================================================\n\n/** Connected ports by ID */\nconst ports = new Map<string, MessagePort>();\n\n/** Last heartbeat timestamp per port (for stale port detection) */\nconst lastHeartbeat = new Map<string, number>();\n\n/** Interval for checking stale ports */\nlet heartbeatIntervalId: ReturnType<typeof setInterval> | null = null;\n\n/** Ports are considered stale after this many ms without a heartbeat */\nconst STALE_PORT_THRESHOLD_MS = 60_000;\n\n/** How often to check for stale ports */\nconst HEARTBEAT_CHECK_INTERVAL_MS = 30_000;\n\n/** Counter for generating unique port IDs */\nlet nextPortId = 1;\n\n/** Generate a unique port ID */\nfunction generatePortId(): string {\n return `port_${nextPortId++}_${Date.now()}`;\n}\n\n// ============================================================================\n// Document State Management\n// ============================================================================\n\n/** Track which ports are subscribed to which documents for event broadcasting */\nconst documentSubscriptions = new Map<number, Set<string>>(); // docRef -> Set<portId>\n\n/** Track which ports are using which documents (for cleanup) */\nconst documentUsers = new Map<number, Set<string>>(); // docRef -> Set<portId>\n\n// ============================================================================\n// Shared Document Registry (by documentFamilyId)\n// Enables multiple tabs to share the same WASM document instance\n// ============================================================================\n\n/** Map documentFamilyId -> docRef for sharing documents across tabs */\nconst sharedDocuments = new Map<string, number>();\n\n/** Track which ports are using each shared document (by documentFamilyId) */\nconst sharedDocumentUsers = new Map<string, Set<string>>(); // documentFamilyId -> Set<portId>\n\n/**\n * Subscribe a port to document events.\n */\nfunction subscribeToDocument(docRef: number, portId: string): void {\n if (!documentSubscriptions.has(docRef)) {\n documentSubscriptions.set(docRef, new Set());\n }\n documentSubscriptions.get(docRef)!.add(portId);\n console.log(`[shared-worker] Port ${portId} subscribed to document ${docRef}`);\n}\n\n/**\n * Unsubscribe a port from document events.\n */\nfunction unsubscribeFromDocument(docRef: number, portId: string): void {\n const subscribers = documentSubscriptions.get(docRef);\n if (subscribers) {\n subscribers.delete(portId);\n if (subscribers.size === 0) {\n documentSubscriptions.delete(docRef);\n }\n console.log(`[shared-worker] Port ${portId} unsubscribed from document ${docRef}`);\n }\n}\n\n/**\n * Register a port as using a document (for reference counting).\n */\nfunction registerDocumentUser(docRef: number, portId: string): void {\n if (!documentUsers.has(docRef)) {\n documentUsers.set(docRef, new Set());\n }\n documentUsers.get(docRef)!.add(portId);\n}\n\n/**\n * Unregister a port from a document. Returns true if document should be freed.\n */\nfunction unregisterDocumentUser(docRef: number, portId: string): boolean {\n const users = documentUsers.get(docRef);\n if (users) {\n users.delete(portId);\n if (users.size === 0) {\n documentUsers.delete(docRef);\n return true; // No more users, safe to free\n }\n }\n return false;\n}\n\n// ============================================================================\n// Shared Document Functions (by documentFamilyId)\n// ============================================================================\n\n/**\n * Load or join a shared document by documentFamilyId.\n * If another tab has already loaded this document, returns the existing docRef.\n * If not loaded, loads from provided kddbBytes and registers as shared.\n *\n * @param documentFamilyId - Unique identifier for the document family\n * @param portId - Port ID of the requesting tab\n * @param kddbBytes - KDDB bytes (required if document not already loaded)\n * @returns Object with docRef, shared status, and user count\n */\nfunction loadSharedDocument(\n documentFamilyId: string,\n portId: string,\n kddbBytes?: Uint8Array\n): { docRef: number; shared: boolean; userCount: number } {\n // Check if already loaded by another tab\n if (sharedDocuments.has(documentFamilyId)) {\n const existingDocRef = sharedDocuments.get(documentFamilyId)!;\n\n // Validate docRef is still alive - first check tracking maps, then WASM\n let isValid = false;\n const docUsers = documentUsers.get(existingDocRef);\n if (docUsers && docUsers.size > 0) {\n // Tracking maps show active users - verify WASM doc is still valid\n const documentGetRoot = (self as any).documentGetRoot;\n if (typeof documentGetRoot === 'function') {\n try {\n const root = documentGetRoot(existingDocRef);\n isValid = root !== null && root !== undefined;\n } catch {\n isValid = false;\n }\n } else {\n // Can't validate WASM - trust tracking maps\n isValid = true;\n }\n }\n // If no users in tracking maps, docRef is definitely stale\n\n if (!isValid) {\n console.warn(`[shared-worker] Stale shared document ${documentFamilyId} (docRef: ${existingDocRef}), cleaning up`);\n // Clean up all tracking for this stale entry\n const staleUsers = sharedDocumentUsers.get(documentFamilyId);\n if (staleUsers) {\n for (const uid of staleUsers) {\n unsubscribeFromDocument(existingDocRef, uid);\n unregisterDocumentUser(existingDocRef, uid);\n }\n }\n sharedDocuments.delete(documentFamilyId);\n sharedDocumentUsers.delete(documentFamilyId);\n documentSubscriptions.delete(existingDocRef);\n documentUsers.delete(existingDocRef);\n // Fall through to load from bytes below\n } else {\n // Valid doc - register port as user\n let users = sharedDocumentUsers.get(documentFamilyId);\n if (!users) {\n users = new Set();\n sharedDocumentUsers.set(documentFamilyId, users);\n }\n users.add(portId);\n\n // Also register in the regular document users tracking\n registerDocumentUser(existingDocRef, portId);\n\n // Auto-subscribe to document events\n subscribeToDocument(existingDocRef, portId);\n\n console.log(`[shared-worker] Port ${portId} joined shared document ${documentFamilyId} (docRef: ${existingDocRef}), ${users.size} users`);\n\n return {\n docRef: existingDocRef,\n shared: true,\n userCount: users.size,\n };\n }\n }\n\n // Not loaded - need kddbBytes\n if (!kddbBytes) {\n throw new Error(`Document ${documentFamilyId} not loaded and no bytes provided`);\n }\n\n // Load new document using loadDocument\n const loadDocument = (self as any).loadDocument;\n if (typeof loadDocument !== 'function') {\n throw new Error('loadDocument function not available');\n }\n\n const docRef = loadDocument(kddbBytes);\n if (docRef === 0) {\n throw new Error('Failed to load document from KDDB bytes');\n }\n\n // Register as shared document\n sharedDocuments.set(documentFamilyId, docRef);\n const users = new Set<string>([portId]);\n sharedDocumentUsers.set(documentFamilyId, users);\n\n // Register in regular tracking\n registerDocumentUser(docRef, portId);\n\n // Auto-subscribe to events\n subscribeToDocument(docRef, portId);\n\n console.log(`[shared-worker] Port ${portId} loaded shared document ${documentFamilyId} (docRef: ${docRef})`);\n\n return {\n docRef,\n shared: false,\n userCount: 1,\n };\n}\n\n/**\n * Release this tab's reference to a shared document.\n * Document is freed when all tabs release it.\n *\n * @param documentFamilyId - Document family ID to release\n * @param portId - Port ID releasing the document\n * @returns Object with freed status and remaining user count\n */\nfunction releaseSharedDocument(\n documentFamilyId: string,\n portId: string\n): { freed: boolean; remainingUsers?: number; notFound?: boolean } {\n const docRef = sharedDocuments.get(documentFamilyId);\n\n if (docRef === undefined) {\n return { freed: false, notFound: true };\n }\n\n // Remove this port from shared document users\n const users = sharedDocumentUsers.get(documentFamilyId);\n if (users) {\n users.delete(portId);\n\n // Unsubscribe from events\n unsubscribeFromDocument(docRef, portId);\n\n // Unregister from regular tracking\n unregisterDocumentUser(docRef, portId);\n\n // If no users left, free the document\n if (users.size === 0) {\n console.log(`[shared-worker] Freeing shared document ${documentFamilyId} (docRef: ${docRef}) - no more users`);\n\n // Free the document\n try {\n const freeDocument = (self as any).freeDocument;\n if (typeof freeDocument === 'function') {\n freeDocument(docRef);\n }\n } catch (error) {\n console.error(`[shared-worker] Error freeing document ${docRef}:`, error);\n }\n\n // Clean up registry\n sharedDocuments.delete(documentFamilyId);\n sharedDocumentUsers.delete(documentFamilyId);\n documentSubscriptions.delete(docRef);\n\n return { freed: true };\n }\n\n console.log(`[shared-worker] Port ${portId} released shared document ${documentFamilyId}, ${users.size} users remaining`);\n return { freed: false, remainingUsers: users.size };\n }\n\n return { freed: false, notFound: true };\n}\n\n/**\n * Check if a document is already loaded as a shared document.\n *\n * @param documentFamilyId - Document family ID to check\n * @returns true if document is loaded, false otherwise\n */\nfunction isDocumentShared(documentFamilyId: string): boolean {\n return sharedDocuments.has(documentFamilyId);\n}\n\n/**\n * Get the docRef for a shared document by documentFamilyId.\n *\n * @param documentFamilyId - Document family ID to look up\n * @returns docRef if found, undefined otherwise\n */\nfunction getSharedDocumentRef(documentFamilyId: string): number | undefined {\n return sharedDocuments.get(documentFamilyId);\n}\n\n/**\n * Invalidate a shared document and notify other tabs.\n * Called when one tab force-reloads a document.\n *\n * @param documentFamilyId - Document family ID being invalidated\n * @param portId - Port ID of the tab initiating the invalidation\n * @param reason - Reason for invalidation (e.g., 'reload', 'server-update')\n */\nfunction invalidateSharedDocument(\n documentFamilyId: string,\n portId: string,\n reason: string\n): void {\n const docRef = sharedDocuments.get(documentFamilyId);\n\n if (docRef === undefined) {\n return;\n }\n\n const users = sharedDocumentUsers.get(documentFamilyId);\n if (!users) {\n return;\n }\n\n // Notify all OTHER tabs using this document\n for (const userPortId of users) {\n if (userPortId !== portId) {\n const port = ports.get(userPortId);\n if (port) {\n try {\n port.postMessage({\n type: 'documentInvalidated',\n documentFamilyId,\n reason,\n initiatorPortId: portId,\n });\n console.log(`[shared-worker] Notified port ${userPortId} of document invalidation: ${documentFamilyId}`);\n } catch (error) {\n console.error(`[shared-worker] Error notifying port ${userPortId}:`, error);\n }\n }\n }\n }\n}\n\n/**\n * Cleanup all resources associated with a port.\n */\nfunction cleanupPort(portId: string): void {\n console.log(`[shared-worker] Cleaning up port ${portId}`);\n\n // Remove from all document subscriptions\n for (const [docRef, subscribers] of documentSubscriptions) {\n subscribers.delete(portId);\n if (subscribers.size === 0) {\n documentSubscriptions.delete(docRef);\n }\n }\n\n // Release all shared documents this port was using\n for (const [documentFamilyId, users] of sharedDocumentUsers) {\n if (users.has(portId)) {\n users.delete(portId);\n\n // If last user, free document and clean up\n if (users.size === 0) {\n const docRef = sharedDocuments.get(documentFamilyId);\n if (docRef !== undefined) {\n console.log(`[shared-worker] Freeing shared document ${documentFamilyId} (docRef: ${docRef}) - port ${portId} was last user`);\n try {\n const freeDocument = (self as any).freeDocument;\n if (typeof freeDocument === 'function') {\n freeDocument(docRef);\n }\n } catch (error) {\n console.error(`[shared-worker] Error freeing document ${docRef}:`, error);\n }\n sharedDocuments.delete(documentFamilyId);\n documentUsers.delete(docRef);\n }\n sharedDocumentUsers.delete(documentFamilyId);\n }\n }\n }\n\n // Unregister from all non-shared document users\n for (const [docRef, users] of documentUsers) {\n users.delete(portId);\n if (users.size === 0) {\n // Check if this is a shared document - if so, it's already handled above\n let isShared = false;\n for (const [, sharedDocRef] of sharedDocuments) {\n if (sharedDocRef === docRef) {\n isShared = true;\n break;\n }\n }\n\n if (!isShared) {\n // No ports using this non-shared document, free it\n console.log(`[shared-worker] Freeing non-shared document ${docRef} - no more users`);\n try {\n const freeDocument = (self as any).freeDocument;\n if (typeof freeDocument === 'function') {\n freeDocument(docRef);\n }\n } catch (error) {\n console.error(`[shared-worker] Error freeing document ${docRef}:`, error);\n }\n }\n documentUsers.delete(docRef);\n }\n }\n\n // Remove heartbeat tracking\n lastHeartbeat.delete(portId);\n\n // Remove port\n ports.delete(portId);\n\n // Stop heartbeat checking if no ports remain\n if (ports.size === 0 && heartbeatIntervalId) {\n clearInterval(heartbeatIntervalId);\n heartbeatIntervalId = null;\n }\n}\n\n/**\n * Check for and clean up stale ports that haven't sent a heartbeat recently.\n * This catches tab crashes, mobile eviction, and other cases where\n * beforeunload doesn't fire.\n */\nfunction checkForStalePorts(): void {\n const now = Date.now();\n // Collect stale ports first to avoid modifying map during iteration\n const stalePorts: string[] = [];\n for (const [portId, lastBeat] of lastHeartbeat) {\n if (now - lastBeat >= STALE_PORT_THRESHOLD_MS) {\n stalePorts.push(portId);\n }\n }\n for (const portId of stalePorts) {\n console.log(`[shared-worker] Port ${portId} stale (no heartbeat for ${STALE_PORT_THRESHOLD_MS}ms), cleaning up`);\n cleanupPort(portId); // cleanupPort already removes from lastHeartbeat\n }\n}\n\n// ============================================================================\n// Event Broadcasting\n// ============================================================================\n\n/**\n * Broadcast an event to all ports subscribed to a document.\n */\nfunction broadcastToSubscribers(docRef: number, eventType: string, detail: unknown): void {\n const subscribers = documentSubscriptions.get(docRef);\n console.log(`[shared-worker] broadcastToSubscribers called docRef=${docRef} eventType=${eventType} subscriberCount=${subscribers?.size ?? 0}`);\n if (!subscribers || subscribers.size === 0) {\n console.log(`[shared-worker] No subscribers for document ${docRef}, event not broadcast`);\n return;\n }\n\n const message: WorkerWasmEventMessage = {\n type: 'wasmEvent',\n eventType,\n detail,\n documentRef: docRef,\n };\n\n for (const portId of subscribers) {\n const port = ports.get(portId);\n if (port) {\n try {\n console.log(`[shared-worker] Posting wasmEvent to port ${portId}`);\n port.postMessage(message);\n console.log(`[shared-worker] Posted wasmEvent to port ${portId} successfully`);\n } catch (error) {\n console.error(`[shared-worker] Error posting to port ${portId}:`, error);\n }\n } else {\n console.warn(`[shared-worker] Port ${portId} not found in ports map, cannot send event`);\n }\n }\n}\n\n/**\n * Broadcast an event to ALL connected ports.\n */\nfunction broadcastToAll(message: unknown): void {\n for (const [portId, port] of ports) {\n try {\n port.postMessage(message);\n } catch (error) {\n console.error(`[shared-worker] Error posting to port ${portId}:`, error);\n }\n }\n}\n\n// ============================================================================\n// Worker State\n// ============================================================================\n\nlet initialized = false;\nlet initPromise: Promise<void> | null = null;\nlet config: WorkerConfig = {};\n\n// ============================================================================\n// Event Forwarding from WASM\n// ============================================================================\n\n/**\n * Set up event forwarding from WASM to connected ports.\n *\n * SIMPLIFIED ARCHITECTURE:\n * Go WASM calls document.dispatchEvent(CustomEvent) with JSON string detail.\n * We parse the JSON once here and broadcast directly to subscribers.\n * No intermediate self.dispatchEvent → addEventListener dance needed.\n */\nfunction setupEventForwarding(): void {\n // Create a document shim for Go WASM to dispatch events\n const documentShim = {\n addEventListener: (type: string, handler: EventListener) => {\n // Go WASM may register listeners, but we handle events directly in dispatchEvent\n console.log(`[shared-worker] Event listener registered for: ${type} (handled in dispatchEvent)`);\n },\n removeEventListener: (type: string, handler: EventListener) => {\n // No-op - we don't use addEventListener\n },\n dispatchEvent: (event: Event) => {\n // Handle CustomEvents from Go WASM directly - no intermediate dispatch needed\n if (!(event instanceof CustomEvent)) {\n return true;\n }\n\n const eventType = event.type;\n const rawDetail = event.detail;\n\n // Parse JSON detail once (Go sends it as a JSON string)\n let parsedDetail: any;\n try {\n parsedDetail = typeof rawDetail === 'string' ? JSON.parse(rawDetail) : rawDetail;\n } catch (e) {\n console.warn(`[shared-worker] Failed to parse ${eventType} detail:`, e);\n parsedDetail = rawDetail;\n }\n\n const docRef = parsedDetail?.documentRef;\n console.log(`[shared-worker] dispatchEvent: ${eventType}`, { docRef, eventType: parsedDetail?.eventType });\n\n if (docRef !== undefined) {\n // Document-specific event - broadcast to subscribers only\n // Pass the PARSED detail so UI doesn't need to parse again\n broadcastToSubscribers(docRef, eventType, parsedDetail);\n } else {\n // Global event - broadcast to all ports\n broadcastToAll({\n type: 'wasmEvent',\n eventType: eventType,\n detail: parsedDetail,\n } as WorkerWasmEventMessage);\n }\n\n return true;\n },\n createElement: () => null,\n body: null,\n documentElement: null,\n };\n\n (self as any).document = documentShim;\n\n console.log('[shared-worker] Event forwarding configured (simplified architecture)');\n}\n\n// ============================================================================\n// WASM Loading (same as dedicated worker)\n// ============================================================================\n\nasync function initializeSqlJs(): Promise<void> {\n const sqlJsUrl = 'https://sql.js.org/dist/sql-wasm.js';\n const sqlWasmUrl = 'https://sql.js.org/dist/sql-wasm.wasm';\n\n try {\n const response = await fetch(sqlJsUrl);\n if (!response.ok) {\n throw new Error(`Failed to fetch sql-wasm.js: ${response.statusText}`);\n }\n const code = await response.text();\n\n const wrappedCode = `\n (function(module, exports) {\n ${code}\n return module.exports;\n })\n `;\n\n // eslint-disable-next-line no-eval\n const moduleFactory = eval(wrappedCode);\n const mockModule = { exports: {} as any };\n const initSqlJs = moduleFactory(mockModule, mockModule.exports);\n\n if (typeof initSqlJs !== 'function') {\n throw new Error('initSqlJs not found after loading sql-wasm.js');\n }\n\n const sqlConfig = {\n locateFile: () => sqlWasmUrl,\n };\n\n const SQL = await initSqlJs(sqlConfig);\n setSqlInstance(SQL);\n exposeBridgeFunctions();\n\n // Expose loadDocument function\n (self as any).loadDocument = (bytes: Uint8Array): number => {\n const handle = loadDirectOp(bytes);\n if (handle === 0) {\n console.error('[shared-worker] Failed to load database');\n return 0;\n }\n return (self as any).createDocumentFromHandle(handle);\n };\n\n console.log('[shared-worker] sql.js initialized from official CDN');\n } catch (error) {\n console.error('[shared-worker] Failed to initialize sql.js:', error);\n throw new Error(`Failed to initialize sql.js: ${error}`);\n }\n}\n\nasync function loadWasmExec(): Promise<void> {\n if ((self as any).Go) {\n return;\n }\n\n const baseUrl = config.wasmBaseUrl || self.location.origin;\n const wasmExecUrl = `${baseUrl}/wasm_exec.js`;\n\n try {\n const response = await fetch(wasmExecUrl);\n if (!response.ok) {\n throw new Error(`Failed to fetch wasm_exec.js: ${response.statusText}`);\n }\n const code = await response.text();\n // eslint-disable-next-line no-eval\n eval(code);\n console.log('[shared-worker] wasm_exec.js loaded');\n } catch (error) {\n throw new Error(`Failed to load wasm_exec.js: ${error}`);\n }\n}\n\nasync function loadGoWasm(): Promise<void> {\n const baseUrl = config.wasmBaseUrl || self.location.origin;\n // Add cache-busting version if provided\n const versionParam = config.wasmVersion ? `?v=${config.wasmVersion}` : '';\n const wasmUrl = `${baseUrl}/kodexa.wasm${versionParam}`;\n\n const response = await fetch(wasmUrl);\n if (!response.ok) {\n throw new Error(`Failed to fetch kodexa.wasm: ${response.statusText}`);\n }\n const wasmBytes = await response.arrayBuffer();\n\n const go = new (self as any).Go();\n const result = await WebAssembly.instantiate(wasmBytes, go.importObject);\n go.run(result.instance);\n\n const logLevel = config.logLevel || 'warn';\n if ((self as any).kodexa_setLogLevel) {\n (self as any).kodexa_setLogLevel(logLevel);\n }\n\n console.log('[shared-worker] Go WASM loaded');\n}\n\nasync function initialize(workerConfig?: WorkerConfig): Promise<void> {\n if (initialized) {\n return;\n }\n\n if (initPromise) {\n return initPromise;\n }\n\n config = workerConfig || {};\n\n initPromise = (async () => {\n try {\n setupEventForwarding();\n await initializeSqlJs();\n await loadWasmExec();\n await loadGoWasm();\n initialized = true;\n console.log('[shared-worker] Kodexa WASM fully initialized');\n } catch (error) {\n console.error('[shared-worker] Initialization failed:', error);\n throw error;\n }\n })();\n\n return initPromise;\n}\n\n// ============================================================================\n// Message Handling\n// ============================================================================\n\n/**\n * Handle RPC call from a port.\n */\nfunction handleCall(request: SharedWorkerRequest): SharedWorkerResponse {\n const { id, method, args, portId } = request;\n\n try {\n const fn = (self as any)[method];\n if (typeof fn !== 'function') {\n return {\n id,\n portId,\n success: false,\n error: `Function '${method}' not found on globalThis`,\n };\n }\n\n const result = fn(...(args || []));\n\n // Track document usage when creating/loading documents\n if (method === 'createDocument' || method === 'createDocumentFromText' ||\n method === 'createDocumentFromJson' || method === 'createDocumentFromKddbBytes' ||\n method === 'loadDocument') {\n if (typeof result === 'number' && result > 0) {\n registerDocumentUser(result, portId);\n }\n }\n\n // Track document disposal\n if (method === 'freeDocument' && args && args.length > 0) {\n const docRef = args[0] as number;\n const shouldFree = unregisterDocumentUser(docRef, portId);\n if (!shouldFree) {\n // Other ports still using this document, don't actually free it\n return { id, portId, success: true, result: undefined };\n }\n }\n\n return { id, portId, success: true, result };\n } catch (error) {\n return {\n id,\n portId,\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n/**\n * Handle messages from a connected port.\n */\nfunction handlePortMessage(portId: string, port: MessagePort, event: MessageEvent<SharedWorkerInboundMessage>): void {\n const data = event.data;\n\n // Handle init message\n if ('type' in data && data.type === 'init') {\n (async () => {\n try {\n await initialize(data.config);\n const readyMessage: SharedWorkerReadyMessage = { type: 'ready', portId };\n port.postMessage(readyMessage);\n } catch (error) {\n const errorMessage: WorkerErrorMessage = {\n type: 'error',\n error: error instanceof Error ? error.message : String(error),\n };\n port.postMessage(errorMessage);\n }\n })();\n return;\n }\n\n // Handle subscription messages\n if ('type' in data && data.type === 'subscribe') {\n subscribeToDocument(data.docRef, portId);\n return;\n }\n\n if ('type' in data && data.type === 'unsubscribe') {\n unsubscribeFromDocument(data.docRef, portId);\n return;\n }\n\n // Handle shared document messages\n if ('type' in data && data.type === 'loadSharedDocument') {\n const { documentFamilyId, kddbBytes, requestId } = data as any;\n if (!initialized) {\n port.postMessage({\n type: 'sharedDocumentResponse',\n success: false,\n error: 'Worker not initialized',\n requestType: 'loadSharedDocument',\n requestId,\n });\n return;\n }\n\n try {\n const result = loadSharedDocument(documentFamilyId, portId, kddbBytes);\n port.postMessage({\n type: 'sharedDocumentResponse',\n success: true,\n requestType: 'loadSharedDocument',\n requestId,\n ...result,\n });\n } catch (error) {\n port.postMessage({\n type: 'sharedDocumentResponse',\n success: false,\n error: error instanceof Error ? error.message : String(error),\n requestType: 'loadSharedDocument',\n requestId,\n });\n }\n return;\n }\n\n if ('type' in data && data.type === 'releaseSharedDocument') {\n const { documentFamilyId, requestId } = data as any;\n try {\n const result = releaseSharedDocument(documentFamilyId, portId);\n port.postMessage({\n type: 'sharedDocumentResponse',\n success: true,\n requestType: 'releaseSharedDocument',\n requestId,\n ...result,\n });\n } catch (error) {\n port.postMessage({\n type: 'sharedDocumentResponse',\n success: false,\n error: error instanceof Error ? error.message : String(error),\n requestType: 'releaseSharedDocument',\n requestId,\n });\n }\n return;\n }\n\n if ('type' in data && data.type === 'isDocumentShared') {\n const { documentFamilyId, requestId } = data as any;\n const shared = isDocumentShared(documentFamilyId);\n const docRef = getSharedDocumentRef(documentFamilyId);\n port.postMessage({\n type: 'sharedDocumentResponse',\n success: true,\n requestType: 'isDocumentShared',\n requestId,\n shared,\n docRef,\n });\n return;\n }\n\n if ('type' in data && data.type === 'invalidateSharedDocument') {\n const { documentFamilyId, reason, requestId } = data as any;\n invalidateSharedDocument(documentFamilyId, portId, reason || 'reload');\n port.postMessage({\n type: 'sharedDocumentResponse',\n success: true,\n requestType: 'invalidateSharedDocument',\n requestId,\n });\n return;\n }\n\n // Handle heartbeat message\n if ('type' in data && data.type === 'heartbeat') {\n lastHeartbeat.set(portId, Date.now());\n return;\n }\n\n // Handle disconnect message (clean exit from tab close/reload)\n if ('type' in data && data.type === 'disconnect') {\n console.log(`[shared-worker] Port ${portId} sent disconnect message, cleaning up`);\n cleanupPort(portId);\n return;\n }\n\n // Handle RPC call\n if ('type' in data && data.type === 'call') {\n if (!initialized) {\n const response: SharedWorkerResponse = {\n id: (data as SharedWorkerRequest).id,\n portId,\n success: false,\n error: 'Worker not initialized. Send init message first.',\n };\n port.postMessage(response);\n return;\n }\n\n // Add portId to the request\n const request = { ...data, portId } as SharedWorkerRequest;\n const response = handleCall(request);\n port.postMessage(response);\n }\n}\n\n// ============================================================================\n// SharedWorker Connection Handler\n// ============================================================================\n\nself.onconnect = (event: MessageEvent) => {\n const port = event.ports[0];\n const portId = generatePortId();\n\n console.log(`[shared-worker] New port connected: ${portId}`);\n ports.set(portId, port);\n lastHeartbeat.set(portId, Date.now());\n\n // Set up message handler for this port\n port.onmessage = (e) => handlePortMessage(portId, port, e);\n\n // Handle port closure (tab closed)\n // Note: Not all browsers reliably fire this event\n port.onmessageerror = () => {\n console.log(`[shared-worker] Port ${portId} message error, cleaning up`);\n cleanupPort(portId);\n };\n\n // Start the port\n port.start();\n\n // Start heartbeat checking interval if not already running\n if (!heartbeatIntervalId) {\n heartbeatIntervalId = setInterval(checkForStalePorts, HEARTBEAT_CHECK_INTERVAL_MS);\n }\n\n // If already initialized, send ready immediately\n if (initialized) {\n const readyMessage: SharedWorkerReadyMessage = { type: 'ready', portId };\n port.postMessage(readyMessage);\n }\n\n // Send connected message so port knows its ID\n port.postMessage({ type: 'connected', portId });\n};\n\n// Log that shared worker is ready for connections\nconsole.log('[shared-worker] Kodexa SharedWorker ready for connections');\n"]}
|
package/dist/worker/types.d.ts
CHANGED
|
@@ -154,6 +154,8 @@ export interface SharedDocumentLoadMessage {
|
|
|
154
154
|
documentFamilyId: string;
|
|
155
155
|
/** KDDB bytes - required if document not already loaded by another tab */
|
|
156
156
|
kddbBytes?: Uint8Array;
|
|
157
|
+
/** Request ID for correlating responses */
|
|
158
|
+
requestId?: string;
|
|
157
159
|
}
|
|
158
160
|
/**
|
|
159
161
|
* Release this tab's reference to a shared document.
|
|
@@ -161,6 +163,8 @@ export interface SharedDocumentLoadMessage {
|
|
|
161
163
|
export interface SharedDocumentReleaseMessage {
|
|
162
164
|
type: 'releaseSharedDocument';
|
|
163
165
|
documentFamilyId: string;
|
|
166
|
+
/** Request ID for correlating responses */
|
|
167
|
+
requestId?: string;
|
|
164
168
|
}
|
|
165
169
|
/**
|
|
166
170
|
* Check if a document is already loaded as shared.
|
|
@@ -168,6 +172,8 @@ export interface SharedDocumentReleaseMessage {
|
|
|
168
172
|
export interface SharedDocumentCheckMessage {
|
|
169
173
|
type: 'isDocumentShared';
|
|
170
174
|
documentFamilyId: string;
|
|
175
|
+
/** Request ID for correlating responses */
|
|
176
|
+
requestId?: string;
|
|
171
177
|
}
|
|
172
178
|
/**
|
|
173
179
|
* Invalidate a shared document and notify other tabs.
|
|
@@ -176,6 +182,20 @@ export interface SharedDocumentInvalidateMessage {
|
|
|
176
182
|
type: 'invalidateSharedDocument';
|
|
177
183
|
documentFamilyId: string;
|
|
178
184
|
reason?: string;
|
|
185
|
+
/** Request ID for correlating responses */
|
|
186
|
+
requestId?: string;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Heartbeat message sent periodically by each port to indicate it's still alive.
|
|
190
|
+
*/
|
|
191
|
+
export interface HeartbeatMessage {
|
|
192
|
+
type: 'heartbeat';
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Disconnect message sent by a port before it closes (e.g., tab close/reload).
|
|
196
|
+
*/
|
|
197
|
+
export interface DisconnectMessage {
|
|
198
|
+
type: 'disconnect';
|
|
179
199
|
}
|
|
180
200
|
/**
|
|
181
201
|
* Response to shared document operations.
|
|
@@ -184,6 +204,8 @@ export interface SharedDocumentResponse {
|
|
|
184
204
|
type: 'sharedDocumentResponse';
|
|
185
205
|
success: boolean;
|
|
186
206
|
requestType: 'loadSharedDocument' | 'releaseSharedDocument' | 'isDocumentShared' | 'invalidateSharedDocument';
|
|
207
|
+
/** Echoed request ID for correlating responses to requests */
|
|
208
|
+
requestId?: string;
|
|
187
209
|
error?: string;
|
|
188
210
|
/** For loadSharedDocument: the document reference */
|
|
189
211
|
docRef?: number;
|
|
@@ -214,7 +236,7 @@ export type SharedWorkerOutboundMessage = SharedWorkerResponse | SharedWorkerRea
|
|
|
214
236
|
/**
|
|
215
237
|
* All possible messages from main thread to SharedWorker.
|
|
216
238
|
*/
|
|
217
|
-
export type SharedWorkerInboundMessage = SharedWorkerRequest | SharedWorkerInitMessage | SharedWorkerSubscribeMessage | SharedWorkerUnsubscribeMessage | SharedDocumentLoadMessage | SharedDocumentReleaseMessage | SharedDocumentCheckMessage | SharedDocumentInvalidateMessage;
|
|
239
|
+
export type SharedWorkerInboundMessage = SharedWorkerRequest | SharedWorkerInitMessage | SharedWorkerSubscribeMessage | SharedWorkerUnsubscribeMessage | SharedDocumentLoadMessage | SharedDocumentReleaseMessage | SharedDocumentCheckMessage | SharedDocumentInvalidateMessage | HeartbeatMessage | DisconnectMessage;
|
|
218
240
|
/**
|
|
219
241
|
* Reference to an object created earlier in the same transaction.
|
|
220
242
|
* Used when creating attributes on newly-created data objects.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/worker/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/worker/types.ts"],"names":[],"mappings":"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"}
|