arcane-os 0.3.0 → 0.3.2

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 (153) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +86 -117
  3. package/bin/arcane-test.mjs +170 -46
  4. package/browser-runtime/ai/browser-speech-artifacts.mjs +887 -909
  5. package/browser-runtime/ai/browser-speech-providers.mjs +96 -152
  6. package/browser-runtime/ai/browser-wasm-llm-provider.mjs +627 -819
  7. package/browser-runtime/ai/browser-wasm.mjs +24 -35
  8. package/browser-runtime/ai/browser-wllama-runtime.mjs +64 -316
  9. package/browser-runtime/ai/model-controller.mjs +584 -181
  10. package/browser-runtime/ai/speech-worker-client.mjs +8 -146
  11. package/browser-runtime/ai/speech-worker-runtime.mjs +643 -363
  12. package/browser-runtime/dom-event-instrumentation.mjs +55 -147
  13. package/browser-runtime/event-manager.mjs +239 -624
  14. package/package.json +5 -6
  15. package/runtime/arcane/components/app-bar.html +3 -15
  16. package/runtime/arcane/components/assistant-panel.html +10 -10
  17. package/runtime/arcane/components/calculator.html +1 -1
  18. package/runtime/arcane/components/chat.html +1359 -135
  19. package/runtime/arcane/components/conversation-view.html +2 -2
  20. package/runtime/arcane/components/document-inspector.html +11 -17
  21. package/runtime/arcane/components/file-manager.html +13 -56
  22. package/runtime/arcane/components/markdown-document.html +82 -281
  23. package/runtime/arcane/components/markdown-editor.html +7 -10
  24. package/runtime/arcane/components/media-embed.html +6 -6
  25. package/runtime/arcane/components/screen-capture.html +4 -4
  26. package/runtime/arcane/components/source-explanation.html +2 -2
  27. package/runtime/arcane/components/speech.html +112 -68
  28. package/runtime/arcane/components/terminal-workspace.html +4 -4
  29. package/runtime/arcane/components/theme-editor.html +1 -1
  30. package/runtime/arcane/components/unified-inbox.html +2 -2
  31. package/runtime/arcane/components/voice-transcription.html +31 -21
  32. package/runtime/arcane/entities/Calculation.js +2 -3
  33. package/runtime/arcane/entities/Chat.js +228 -43
  34. package/runtime/arcane/entities/Preference.js +3 -5
  35. package/runtime/arcane/entities/Weather.js +5 -5
  36. package/runtime/arcane/modules/AI.js +1050 -427
  37. package/runtime/arcane/modules/AIProviderRuntime.js +658 -363
  38. package/runtime/arcane/modules/AIResponseLength.js +9 -19
  39. package/runtime/arcane/modules/AIRuntimeState.js +109 -72
  40. package/runtime/arcane/modules/ArcaneNavigationPolicy.js +45 -32
  41. package/runtime/arcane/modules/BrowserTestSuite.js +78 -122
  42. package/runtime/arcane/modules/CalculatorEngine.js +9 -9
  43. package/runtime/arcane/modules/CommunicationAppController.js +3 -7
  44. package/runtime/arcane/modules/ComponentContracts.js +30 -32
  45. package/runtime/arcane/modules/ConfiguredAIChatSession.js +281 -230
  46. package/runtime/arcane/modules/ConversationActionItems.js +26 -59
  47. package/runtime/arcane/modules/ConversationClosingReport.js +34 -61
  48. package/runtime/arcane/modules/ConversationTimebox.js +27 -15
  49. package/runtime/arcane/modules/DBOPFSDocumentLibrary.js +152 -344
  50. package/runtime/arcane/modules/DocumentLexicalSearch.js +25 -91
  51. package/runtime/arcane/modules/HTMLImport.js +54 -1
  52. package/runtime/arcane/modules/IsolatedModelQuestionRunner.js +40 -203
  53. package/runtime/arcane/modules/LocalAIReadiness.js +40 -60
  54. package/runtime/arcane/modules/LocalAIReadinessController.js +15 -13
  55. package/runtime/arcane/modules/MD.js +1 -45
  56. package/runtime/arcane/modules/Mail.js +51 -103
  57. package/runtime/arcane/modules/MailOutbox.mjs +95 -193
  58. package/runtime/arcane/modules/MailTransport.mjs +36 -57
  59. package/runtime/arcane/modules/ModelDefinition.js +22 -106
  60. package/runtime/arcane/modules/OpenMeteoWeatherProvider.js +39 -101
  61. package/runtime/arcane/modules/PersistentAIChatSession.js +281 -18
  62. package/runtime/arcane/modules/PreferenceStore.js +102 -30
  63. package/runtime/arcane/modules/RiskSignalAnalyzer.js +8 -9
  64. package/runtime/arcane/modules/ScopedOPFSCache.js +7 -42
  65. package/runtime/arcane/modules/ScreenCapture.js +175 -128
  66. package/runtime/arcane/modules/SpeechPlayback.js +46 -149
  67. package/runtime/arcane/modules/StaticDocumentCatalog.js +173 -407
  68. package/runtime/arcane/modules/ToolCallRouter.js +25 -12
  69. package/runtime/arcane/modules/YouTubeMedia.js +6 -5
  70. package/schemas/arcane-app-bundle.schema.json +13 -78
  71. package/schemas/arcane-app.schema.json +9 -25
  72. package/schemas/arcane-lock.schema.json +18 -151
  73. package/schemas/arcane-package.schema.json +2 -16
  74. package/schemas/native-build-plan.schema.json +119 -122
  75. package/src/app-descriptor.mjs +75 -132
  76. package/src/application-tests.mjs +200 -0
  77. package/src/cli/main.mjs +27 -46
  78. package/src/constants.mjs +3 -4
  79. package/src/dev-server.mjs +30 -324
  80. package/src/doctor.mjs +92 -154
  81. package/src/dom-event-instrumentation.mjs +55 -147
  82. package/src/errors.mjs +2 -3
  83. package/src/event-manager.mjs +239 -624
  84. package/src/event-queue.mjs +3 -3
  85. package/src/import-map.mjs +273 -1028
  86. package/src/index.mjs +14 -16
  87. package/src/installed-sdk-runtime.mjs +40 -62
  88. package/src/integrated-provider-loader.mjs +53 -382
  89. package/src/mail-api.mjs +0 -2
  90. package/src/mail-server.mjs +224 -580
  91. package/src/mail.mjs +4 -10
  92. package/src/native-plan.mjs +163 -598
  93. package/src/native-provider-loader.mjs +104 -1063
  94. package/src/packager/core.mjs +485 -3229
  95. package/src/process.mjs +5 -10
  96. package/src/release-bundle.mjs +292 -2405
  97. package/src/runtime.mjs +76 -396
  98. package/src/scaffold.mjs +30 -80
  99. package/src/sdk-browser-runtime.mjs +70 -626
  100. package/src/source-server.mjs +588 -0
  101. package/src/targets/index.mjs +78 -188
  102. package/src/templates/workspace-template.mjs +19 -135
  103. package/src/testing-loader.mjs +164 -0
  104. package/src/testing.mjs +1 -1
  105. package/src/toolchain.mjs +131 -544
  106. package/src/update-check.mjs +26 -64
  107. package/src/workspace-operation-lock.mjs +139 -430
  108. package/src/workspace-runtime.mjs +112 -779
  109. package/src/workspace.mjs +40 -302
  110. package/browser-runtime/ARCANE_SDK_BROWSER_RELEASE.json +0 -218
  111. package/browser-runtime/ai/ARCANE_AI_BROWSER_SPEECH_COMPONENTS.json +0 -203
  112. package/browser-runtime/ai/ARCANE_AI_BROWSER_WASM_COMPONENTS.json +0 -80
  113. package/browser-runtime/ai/internal/sha256.mjs +0 -166
  114. package/docs/architecture.md +0 -344
  115. package/docs/compatibility.md +0 -36
  116. package/docs/event-manager.md +0 -294
  117. package/docs/platform-targets.md +0 -108
  118. package/docs/publishing.md +0 -201
  119. package/docs/reference/README.md +0 -187
  120. package/docs/reference/ai/browser-speech-package-authority.json +0 -835
  121. package/docs/reference/ai/browser-speech.md +0 -1252
  122. package/docs/reference/ai/browser-wasm.md +0 -530
  123. package/docs/reference/arcane-ollama.md +0 -288
  124. package/docs/reference/availability-and-normalization.md +0 -183
  125. package/docs/reference/behavioral-testing.md +0 -133
  126. package/docs/reference/cli.md +0 -779
  127. package/docs/reference/core/README.md +0 -62
  128. package/docs/reference/core/arcane-ai-contracts.md +0 -907
  129. package/docs/reference/core/arcane-api.md +0 -601
  130. package/docs/reference/core/arcane-entities.md +0 -65
  131. package/docs/reference/core/arcane-events.md +0 -134
  132. package/docs/reference/core/ollama-module.md +0 -181
  133. package/docs/reference/core/reference/arcane-api/ai-and-ollama.md +0 -1909
  134. package/docs/reference/core/reference/arcane-api/applications-terminal-capabilities.md +0 -1057
  135. package/docs/reference/core/reference/arcane-api/core-and-events.md +0 -320
  136. package/docs/reference/core/reference/arcane-api/filesystem-storage-preferences-appearance.md +0 -610
  137. package/docs/reference/core/reference/arcane-api/namespaces.md +0 -1157
  138. package/docs/reference/core/reference/arcane-api/platform-installation-users-system.md +0 -1423
  139. package/docs/reference/core/reference/arcane-api/session-provisioning-diagnostics-development.md +0 -315
  140. package/docs/reference/event-manager.md +0 -1511
  141. package/docs/reference/inventory/package-api.json +0 -3284
  142. package/docs/reference/inventory/runtime-components.json +0 -1011
  143. package/docs/reference/inventory/runtime-entities.json +0 -26
  144. package/docs/reference/inventory/runtime-modules.json +0 -1431
  145. package/docs/reference/mail.md +0 -316
  146. package/docs/reference/protocols.md +0 -677
  147. package/docs/reference/runtime-components.md +0 -1366
  148. package/docs/reference/runtime-entities.md +0 -303
  149. package/docs/reference/runtime-modules.md +0 -2960
  150. package/docs/reference/sdk-api.md +0 -6694
  151. package/docs/roadmap.md +0 -79
  152. package/docs/work-amplification.md +0 -129
  153. package/runtime/ARCANE_RUNTIME_RELEASE.json +0 -826
@@ -1,28 +1,20 @@
1
1
  export const SPEECH_WORKER_PROTOCOL = "arcane-ai-speech-worker/1";
2
2
 
3
+ const completeValue = (value) => value;
4
+
3
5
  const SPEECH_WORKER_ERROR_PROTOCOL = "arcane-ai-speech-worker-error/1";
4
6
 
5
7
  const ARTIFACT_GRAPH_MODULE_GRAPH =
6
8
  "browser-speech-authenticated-artifact-graph";
7
9
  const GRAPH_GUARD_NAME = "__arcaneBrowserSpeechArtifactGraphGuardsV1";
10
+ const MODULE_ROUTER_NAME = "__arcaneBrowserSpeechModuleRouterV1";
8
11
  const NESTED_WORKER_PROTOCOL =
9
12
  "arcane-ai-browser-speech-artifact-module-worker/1";
10
- const STRICT_GRAPH_ADMISSIONS = new Set([
11
- "artifact-graph-network-dbopfs-verified",
12
- "artifact-graph-dbopfs-cache-verified",
13
- "artifact-graph-offline-dbopfs-cache-verified",
14
- "artifact-graph-network-dbopfs-partially-checked",
15
- "artifact-graph-dbopfs-cache-partially-checked",
16
- "artifact-graph-offline-dbopfs-cache-partially-checked",
17
- "artifact-graph-network-dbopfs-unchecked",
18
- "artifact-graph-dbopfs-cache-unchecked",
19
- "artifact-graph-offline-dbopfs-cache-unchecked",
20
- ]);
21
- const ADAPTERS = Object.freeze({
13
+ const ADAPTERS = completeValue({
22
14
  stt: "transformers-whisper",
23
15
  tts: "kokoro-js",
24
16
  });
25
- const ONNX_NAMESPACES = Object.freeze({
17
+ const ONNX_NAMESPACES = completeValue({
26
18
  stt: "transformers-env-backends-onnx-wasm",
27
19
  tts: "kokoro-env-wasm-paths",
28
20
  });
@@ -30,7 +22,7 @@ const ARTIFACT_GRAPH_TRANSFORM_KINDS = new Set([
30
22
  "function-return-this-to-global-this",
31
23
  "typed-array-constructor",
32
24
  ]);
33
- const PUBLIC_WORKER_OPERATIONS = Object.freeze([
25
+ const PUBLIC_WORKER_OPERATIONS = completeValue([
34
26
  "load",
35
27
  "use",
36
28
  "status",
@@ -41,16 +33,16 @@ const TRANSPORT_WORKER_OPERATION_SET = new Set([
41
33
  ...PUBLIC_WORKER_OPERATIONS,
42
34
  "cancel",
43
35
  ]);
44
- const BOTH_WORKER_ROLES = Object.freeze(["stt", "tts"]);
45
- const LOAD_OPERATION = Object.freeze(["load"]);
46
- const USE_OPERATION = Object.freeze(["use"]);
47
- const STATUS_OPERATION = Object.freeze(["status"]);
48
- const UNLOAD_OPERATION = Object.freeze(["unload"]);
49
- const DISPOSE_OPERATION = Object.freeze(["dispose"]);
50
- const UNLOAD_OR_DISPOSE_OPERATIONS = Object.freeze(["unload", "dispose"]);
51
- const LOAD_OR_USE_OPERATIONS = Object.freeze(["load", "use"]);
36
+ const BOTH_WORKER_ROLES = completeValue(["stt", "tts"]);
37
+ const LOAD_OPERATION = completeValue(["load"]);
38
+ const USE_OPERATION = completeValue(["use"]);
39
+ const STATUS_OPERATION = completeValue(["status"]);
40
+ const UNLOAD_OPERATION = completeValue(["unload"]);
41
+ const DISPOSE_OPERATION = completeValue(["dispose"]);
42
+ const UNLOAD_OR_DISPOSE_OPERATIONS = completeValue(["unload", "dispose"]);
43
+ const LOAD_OR_USE_OPERATIONS = completeValue(["load", "use"]);
52
44
  const SDK_WORKER_ERRORS = new WeakSet();
53
- const WORKER_ERROR_MESSAGES = Object.freeze({
45
+ const WORKER_ERROR_MESSAGES = completeValue({
54
46
  ARCANE_AI_REQUEST_ABORTED: "The speech worker operation was cancelled.",
55
47
  ARCANE_AI_NOT_READY: "The speech worker is not loaded.",
56
48
  ARCANE_AI_INVALID_REQUEST: "The speech worker request was rejected.",
@@ -77,10 +69,10 @@ const WORKER_ERROR_MESSAGES = Object.freeze({
77
69
  const WORKER_ERROR_REASON_ADMISSIONS = new Map();
78
70
 
79
71
  function registerWorkerErrorReasons(code, roles, operations, reasons) {
80
- const admission = Object.freeze({
72
+ const admission = completeValue({
81
73
  code,
82
- roles: Object.freeze([...roles]),
83
- operations: Object.freeze([...operations]),
74
+ roles: completeValue([...roles]),
75
+ operations: completeValue([...operations]),
84
76
  });
85
77
  for (const reason of reasons) WORKER_ERROR_REASON_ADMISSIONS.set(reason, admission);
86
78
  }
@@ -183,7 +175,7 @@ registerWorkerErrorReasons("ARCANE_AI_INVALID_REQUEST", ["tts"], LOAD_OPERATION,
183
175
  "tts-default-voice-empty",
184
176
  ]);
185
177
  registerWorkerErrorReasons("ARCANE_AI_INVALID_REQUEST", ["tts"], USE_OPERATION, [
186
- "tts-synthesis-speed-out-of-range",
178
+ "tts-synthesis-speed-not-positive",
187
179
  "tts-synthesis-text-empty",
188
180
  "tts-synthesis-voice-empty",
189
181
  "tts-synthesis-voice-not-declared",
@@ -465,7 +457,11 @@ function workerError(code, message, cause, reason) {
465
457
  }
466
458
 
467
459
  function isSdkWorkerError(value) {
468
- return value instanceof Error && SDK_WORKER_ERRORS.has(value);
460
+ try {
461
+ return value instanceof Error && SDK_WORKER_ERRORS.has(value);
462
+ } catch {
463
+ return false;
464
+ }
469
465
  }
470
466
 
471
467
  function admitWorkerFailure(error, code, message, reason) {
@@ -518,20 +514,237 @@ export function collectSpeechTransferables(value) {
518
514
  }
519
515
 
520
516
  function serializedError(error, role, op) {
521
- const admission = isSdkWorkerError(error)
522
- ? workerErrorReasonAdmission(error.reason, role, op)
517
+ const sdkError = isSdkWorkerError(error);
518
+ let reportedCode;
519
+ let reportedMessage;
520
+ let reportedReason;
521
+ let reportedCause;
522
+ try { reportedCode = Reflect.get(error, "code"); } catch {}
523
+ try { reportedMessage = Reflect.get(error, "message"); } catch {}
524
+ try { reportedReason = Reflect.get(error, "reason"); } catch {}
525
+ if (sdkError) {
526
+ try { reportedCause = Reflect.get(error, "cause"); } catch (cause) {
527
+ reportedCause = cause;
528
+ }
529
+ } else {
530
+ reportedCause = error;
531
+ }
532
+ const admission = sdkError
533
+ ? workerErrorReasonAdmission(reportedReason, role, op)
523
534
  : null;
524
- const admittedCode = isSdkWorkerError(error)
525
- && Object.hasOwn(WORKER_ERROR_MESSAGES, error.code)
526
- && admission?.code === error.code;
527
- const code = admittedCode ? error.code : "ARCANE_AI_PROVIDER_REQUEST_FAILED";
528
- const reason = admittedCode ? error.reason : operationFailureReason(role, op);
529
- return Object.freeze({
535
+ const admittedCode = sdkError
536
+ && Object.hasOwn(WORKER_ERROR_MESSAGES, reportedCode)
537
+ && admission?.code === reportedCode;
538
+ const code = admittedCode ? reportedCode : "ARCANE_AI_PROVIDER_REQUEST_FAILED";
539
+ const reason = admittedCode ? reportedReason : operationFailureReason(role, op);
540
+ const message = typeof reportedMessage === "string" && reportedMessage.length > 0
541
+ ? reportedMessage
542
+ : WORKER_ERROR_MESSAGES[code];
543
+ const envelope = completeValue({
530
544
  protocol: SPEECH_WORKER_ERROR_PROTOCOL,
531
545
  code,
532
- message: WORKER_ERROR_MESSAGES[code],
546
+ message,
533
547
  reason,
534
548
  });
549
+ if (reportedCause !== undefined) {
550
+ envelope.cause = serializedDiagnosticValue(reportedCause);
551
+ }
552
+ return envelope;
553
+ }
554
+
555
+ function fallbackSerializedError(error, role, op) {
556
+ let message;
557
+ try { message = Reflect.get(error, "message"); } catch {}
558
+ return completeValue({
559
+ protocol: SPEECH_WORKER_ERROR_PROTOCOL,
560
+ code: "ARCANE_AI_PROVIDER_REQUEST_FAILED",
561
+ message: typeof message === "string" && message.length > 0
562
+ ? message
563
+ : WORKER_ERROR_MESSAGES.ARCANE_AI_PROVIDER_REQUEST_FAILED,
564
+ reason: operationFailureReason(role, op),
565
+ });
566
+ }
567
+
568
+ function sendSerializedError(send, response, error, role, op, consoleScope) {
569
+ try {
570
+ response.error = serializedError(error, role, op);
571
+ send(response, []);
572
+ } catch (transportError) {
573
+ try {
574
+ consoleScope?.console?.error?.(
575
+ "The speech Worker could not transport its complete failure diagnostic.",
576
+ error,
577
+ transportError,
578
+ );
579
+ } catch {}
580
+ response.error = fallbackSerializedError(error, role, op);
581
+ send(response, []);
582
+ }
583
+ }
584
+
585
+ function diagnosticText(value, fallback) {
586
+ try {
587
+ return String(value);
588
+ } catch {
589
+ return fallback;
590
+ }
591
+ }
592
+
593
+ function defineDiagnosticProperty(target, key, value) {
594
+ Object.defineProperty(target, key, {
595
+ configurable: true,
596
+ enumerable: true,
597
+ value,
598
+ writable: true,
599
+ });
600
+ }
601
+
602
+ function diagnosticType(value) {
603
+ try {
604
+ return Object.prototype.toString.call(value).slice(8, -1);
605
+ } catch {
606
+ return "UninspectableObject";
607
+ }
608
+ }
609
+
610
+ function serializedDiagnosticValue(value, seen = new WeakMap()) {
611
+ if (value === null || value === undefined) return value;
612
+ const type = typeof value;
613
+ if (type !== "object" && type !== "function") {
614
+ return type === "symbol"
615
+ ? diagnosticText(value, "[symbol could not be represented]")
616
+ : value;
617
+ }
618
+ if (seen.has(value)) return seen.get(value);
619
+
620
+ const result = Object.create(null);
621
+ seen.set(value, result);
622
+ let descriptors;
623
+ try {
624
+ descriptors = Object.getOwnPropertyDescriptors(value);
625
+ } catch (error) {
626
+ defineDiagnosticProperty(
627
+ result,
628
+ "inspectionError",
629
+ serializedDiagnosticValue(error, seen),
630
+ );
631
+ return result;
632
+ }
633
+
634
+ const symbolProperties = [];
635
+ for (const key of Reflect.ownKeys(descriptors)) {
636
+ const descriptor = descriptors[key];
637
+ const projected = Object.create(null);
638
+ if (Object.hasOwn(descriptor, "value")) {
639
+ defineDiagnosticProperty(
640
+ projected,
641
+ "value",
642
+ serializedDiagnosticValue(descriptor.value, seen),
643
+ );
644
+ } else {
645
+ defineDiagnosticProperty(projected, "kind", "accessor");
646
+ if (descriptor.get !== undefined) {
647
+ defineDiagnosticProperty(
648
+ projected,
649
+ "get",
650
+ diagnosticText(descriptor.get, "[getter could not be represented]"),
651
+ );
652
+ }
653
+ if (descriptor.set !== undefined) {
654
+ defineDiagnosticProperty(
655
+ projected,
656
+ "set",
657
+ diagnosticText(descriptor.set, "[setter could not be represented]"),
658
+ );
659
+ }
660
+ }
661
+ if (typeof key === "symbol") {
662
+ const symbolProperty = Object.create(null);
663
+ defineDiagnosticProperty(
664
+ symbolProperty,
665
+ "key",
666
+ diagnosticText(key, "[symbol key could not be represented]"),
667
+ );
668
+ defineDiagnosticProperty(symbolProperty, "descriptor", projected);
669
+ symbolProperties.push(symbolProperty);
670
+ continue;
671
+ }
672
+ defineDiagnosticProperty(
673
+ result,
674
+ key,
675
+ Object.hasOwn(projected, "value") ? projected.value : projected,
676
+ );
677
+ }
678
+
679
+ for (const key of ["name", "message", "stack", "code", "reason", "details", "cause"]) {
680
+ if (Object.hasOwn(result, key)) continue;
681
+ try {
682
+ const field = Reflect.get(value, key);
683
+ if (field !== undefined) {
684
+ defineDiagnosticProperty(
685
+ result,
686
+ key,
687
+ serializedDiagnosticValue(field, seen),
688
+ );
689
+ }
690
+ } catch (error) {
691
+ defineDiagnosticProperty(result, key, serializedDiagnosticValue(error, seen));
692
+ }
693
+ }
694
+
695
+ let metadataKey = "$diagnostic";
696
+ while (Object.hasOwn(result, metadataKey)) metadataKey = `$${metadataKey}`;
697
+ const metadata = Object.create(null);
698
+ const valueType = diagnosticType(value);
699
+ defineDiagnosticProperty(metadata, "type", valueType);
700
+ if (symbolProperties.length > 0) {
701
+ defineDiagnosticProperty(metadata, "symbolProperties", symbolProperties);
702
+ }
703
+ try {
704
+ if (type === "function") {
705
+ defineDiagnosticProperty(
706
+ metadata,
707
+ "source",
708
+ diagnosticText(value, "[function could not be represented]"),
709
+ );
710
+ } else if (valueType === "Map") {
711
+ const entries = [];
712
+ for (const [key, entry] of value) {
713
+ entries.push([
714
+ serializedDiagnosticValue(key, seen),
715
+ serializedDiagnosticValue(entry, seen),
716
+ ]);
717
+ }
718
+ defineDiagnosticProperty(metadata, "entries", entries);
719
+ } else if (valueType === "Set") {
720
+ const entries = [];
721
+ for (const entry of value) entries.push(serializedDiagnosticValue(entry, seen));
722
+ defineDiagnosticProperty(metadata, "values", entries);
723
+ } else if (valueType === "Date") {
724
+ defineDiagnosticProperty(metadata, "value", Date.prototype.getTime.call(value));
725
+ } else if (valueType === "RegExp") {
726
+ defineDiagnosticProperty(metadata, "source", value.source);
727
+ defineDiagnosticProperty(metadata, "flags", value.flags);
728
+ defineDiagnosticProperty(metadata, "lastIndex", value.lastIndex);
729
+ } else if (valueType === "ArrayBuffer" || valueType === "SharedArrayBuffer"
730
+ || valueType === "Blob" || valueType === "File") {
731
+ defineDiagnosticProperty(metadata, "value", value);
732
+ } else {
733
+ let view = false;
734
+ try {
735
+ view = ArrayBuffer.isView(value);
736
+ } catch {}
737
+ if (view) defineDiagnosticProperty(metadata, "value", value);
738
+ }
739
+ } catch (error) {
740
+ defineDiagnosticProperty(
741
+ metadata,
742
+ "inspectionError",
743
+ serializedDiagnosticValue(error, seen),
744
+ );
745
+ }
746
+ defineDiagnosticProperty(result, metadataKey, metadata);
747
+ return result;
535
748
  }
536
749
 
537
750
  function workerErrorReasonAdmission(reason, role, op) {
@@ -549,7 +762,10 @@ export function normalizeSpeechWorkerErrorEnvelope(value, role, op) {
549
762
  try {
550
763
  const keys = Reflect.ownKeys(value);
551
764
  if (keys.some((key) => typeof key !== "string")
552
- || keys.sort().join(",") !== "code,message,protocol,reason") return null;
765
+ || ![
766
+ "code,message,protocol,reason",
767
+ "cause,code,message,protocol,reason",
768
+ ].includes(keys.sort().join(","))) return null;
553
769
  descriptors = Object.getOwnPropertyDescriptors(value);
554
770
  } catch {
555
771
  return null;
@@ -563,13 +779,15 @@ export function normalizeSpeechWorkerErrorEnvelope(value, role, op) {
563
779
  const reason = descriptors.reason.value;
564
780
  if (protocol !== SPEECH_WORKER_ERROR_PROTOCOL) return null;
565
781
  if (!Object.hasOwn(WORKER_ERROR_MESSAGES, code)) return null;
566
- if (message !== WORKER_ERROR_MESSAGES[code]) return null;
782
+ if (typeof message !== "string" || message.length < 1) return null;
567
783
  const admission = workerErrorReasonAdmission(reason, role, op);
568
784
  if (admission?.code !== code) return null;
569
- return Object.freeze({
785
+ if (descriptors.cause && !Object.hasOwn(descriptors.cause, "value")) return null;
786
+ return completeValue({
570
787
  code,
571
788
  message,
572
789
  reason,
790
+ ...(descriptors.cause ? { cause: descriptors.cause.value } : {}),
573
791
  });
574
792
  }
575
793
 
@@ -589,6 +807,22 @@ function requiredText(
589
807
  return value.trim();
590
808
  }
591
809
 
810
+ function requiredContent(
811
+ value,
812
+ label,
813
+ reason,
814
+ ) {
815
+ if (typeof value !== "string" || !value.trim()) {
816
+ throw workerError(
817
+ "ARCANE_AI_INVALID_REQUEST",
818
+ `${label} is required.`,
819
+ undefined,
820
+ reason,
821
+ );
822
+ }
823
+ return value;
824
+ }
825
+
592
826
  function requiredSampleRate(value, label, fallback) {
593
827
  const candidate = value ?? fallback;
594
828
  if (!Number.isSafeInteger(candidate) || candidate < 1) {
@@ -695,26 +929,6 @@ function validateConfiguration(configuration, role) {
695
929
  paths.add(file.path);
696
930
  }
697
931
  const runtimePaths = new Set(configuration.runtime.files.map((file) => file.path));
698
- if (
699
- configuration.security?.secure !== true
700
- || typeof configuration.runtime.artifactGraphId !== "string"
701
- || !/^[a-f0-9]{64}$/u.test(configuration.runtime.artifactGraphId)
702
- || (
703
- typeof configuration.runtime.guardCapability !== "string"
704
- || !/^[a-f0-9]{64}$/u.test(configuration.runtime.guardCapability)
705
- || !STRICT_GRAPH_ADMISSIONS.has(configuration.runtime.artifactGraphAdmission)
706
- || !configuration.runtime.edges
707
- || typeof configuration.runtime.edges !== "object"
708
- || !Array.isArray(configuration.runtime.transforms)
709
- )
710
- ) {
711
- throw workerError(
712
- "ARCANE_AI_ARTIFACT_GRAPH_CONFIGURATION_INVALID",
713
- "Explicit secure:true plus authenticated artifact graph identity, admission, edges, and transforms are required.",
714
- undefined,
715
- "artifact-graph-worker-configuration-incomplete",
716
- );
717
- }
718
932
  const wasm = configuration.runtime.onnxWasm;
719
933
  if (
720
934
  !wasm
@@ -722,17 +936,17 @@ function validateConfiguration(configuration, role) {
722
936
  || !runtimePaths.has(wasm.mjsPath)
723
937
  || !runtimePaths.has(wasm.wasmPath)
724
938
  ) {
725
- throw workerError(
726
- "ARCANE_AI_ARTIFACT_GRAPH_CONFIGURATION_INVALID",
727
- "The authenticated ONNX Runtime Web MJS/WASM pair is incomplete or uses the wrong namespace.",
939
+ throw workerError(
940
+ "ARCANE_AI_ARTIFACT_GRAPH_CONFIGURATION_INVALID",
941
+ "The ONNX Runtime Web MJS/WASM pair is incomplete or uses the wrong namespace.",
728
942
  undefined,
729
943
  "artifact-graph-onnx-wasm-configuration-mismatch",
730
944
  );
731
945
  }
732
946
  if (role === "tts" && wasm.numThreads !== undefined) {
733
- throw workerError(
734
- "ARCANE_AI_ARTIFACT_GRAPH_CONFIGURATION_INVALID",
735
- "Kokoro does not expose a verified numThreads configuration field.",
947
+ throw workerError(
948
+ "ARCANE_AI_ARTIFACT_GRAPH_CONFIGURATION_INVALID",
949
+ "Kokoro does not expose a numThreads configuration field.",
736
950
  undefined,
737
951
  "kokoro-env-num-threads-field-not-exposed",
738
952
  );
@@ -763,17 +977,6 @@ function validateConfiguration(configuration, role) {
763
977
  );
764
978
  }
765
979
  }
766
- if (
767
- configuration.runtime.negativeRuntimeRequestUrls !== undefined
768
- && !Array.isArray(configuration.runtime.negativeRuntimeRequestUrls)
769
- ) {
770
- throw workerError(
771
- "ARCANE_AI_ARTIFACT_GRAPH_CONFIGURATION_INVALID",
772
- "Artifact graph negative runtime request routes must be an array.",
773
- undefined,
774
- "artifact-graph-negative-request-routes-not-array",
775
- );
776
- }
777
980
  }
778
981
  return configuration;
779
982
  }
@@ -794,6 +997,9 @@ function absoluteRequestUrl(value, scope) {
794
997
  }
795
998
  }
796
999
 
1000
+ // Dormant hardening retained for future review only. The closed route reader,
1001
+ // cache admission, and legacy fetch isolation below are not used by ordinary
1002
+ // execution and must not be enabled without explicit user review.
797
1003
  function createArtifactRoutes(scope, configuration) {
798
1004
  const positive = new Map();
799
1005
  const negative = new Set();
@@ -833,7 +1039,7 @@ function createArtifactRoutes(scope, configuration) {
833
1039
  }
834
1040
  negative.add(absolute);
835
1041
  }
836
- return Object.freeze({ files, positive, negative });
1042
+ return completeValue({ files, positive, negative });
837
1043
  }
838
1044
 
839
1045
  function requestMethod(input, init, scope) {
@@ -951,16 +1157,16 @@ function createRouteReader(scope, configuration, originalFetch) {
951
1157
  function resolve(input) {
952
1158
  const absolute = absoluteRequestUrl(input, scope);
953
1159
  const file = routes.positive.get(absolute);
954
- if (file) return Object.freeze({ kind: "file", absolute, file });
1160
+ if (file) return completeValue({ kind: "file", absolute, file });
955
1161
  if (routes.negative.has(absolute)) {
956
- return Object.freeze({ kind: "negative", absolute, file: null });
1162
+ return completeValue({ kind: "negative", absolute, file: null });
957
1163
  }
958
1164
  return null;
959
1165
  }
960
1166
 
961
1167
  function cacheForPaths(targetPaths) {
962
1168
  const admittedPaths = new Set(targetPaths);
963
- return Object.freeze({
1169
+ return completeValue({
964
1170
  async match(input) {
965
1171
  const resolution = resolve(input);
966
1172
  if (
@@ -1005,13 +1211,13 @@ function createRouteReader(scope, configuration, originalFetch) {
1005
1211
  return false;
1006
1212
  },
1007
1213
  async keys() {
1008
- return Object.freeze([]);
1214
+ return completeValue([]);
1009
1215
  },
1010
1216
  });
1011
1217
  }
1012
1218
 
1013
1219
  const cache = cacheForPaths(routes.files.map((file) => file.path));
1014
- return Object.freeze({ cache, cacheForPaths, resolve, responseFor, routes });
1220
+ return completeValue({ cache, cacheForPaths, resolve, responseFor, routes });
1015
1221
  }
1016
1222
 
1017
1223
  function installLegacyAuthorizedFetch(scope, configuration) {
@@ -1051,11 +1257,11 @@ function installLegacyAuthorizedFetch(scope, configuration) {
1051
1257
  authorized,
1052
1258
  "speech-worker-fetch-isolation-unavailable",
1053
1259
  );
1054
- return Object.freeze({ cache: null, cleanup: restore });
1260
+ return completeValue({ cache: null, cleanup: restore });
1055
1261
  }
1056
1262
 
1057
1263
  function installDeniedCacheIsolation(scope) {
1058
- const denied = Object.freeze({
1264
+ const denied = completeValue({
1059
1265
  async open() {
1060
1266
  throw workerError(
1061
1267
  "ARCANE_AI_UNDECLARED_ARTIFACT",
@@ -1076,7 +1282,7 @@ function installDeniedCacheIsolation(scope) {
1076
1282
  return false;
1077
1283
  },
1078
1284
  async keys() {
1079
- return Object.freeze([]);
1285
+ return completeValue([]);
1080
1286
  },
1081
1287
  async delete() {
1082
1288
  return false;
@@ -1224,7 +1430,7 @@ function typedArrayIntrinsics(scope) {
1224
1430
  "artifact-graph-typed-array-validation-unavailable",
1225
1431
  );
1226
1432
  }
1227
- return Object.freeze({
1433
+ return completeValue({
1228
1434
  constructors,
1229
1435
  dataViewPrototype: DataViewConstructor?.prototype ?? null,
1230
1436
  getPrototypeOf: Object.getPrototypeOf,
@@ -1294,6 +1500,9 @@ function nestedWorkerFailureEvent(scope, error) {
1294
1500
  return event;
1295
1501
  }
1296
1502
 
1503
+ // Dormant hardening retained for future review only. Ordinary speech execution
1504
+ // never installs this guard, its declared-edge admission, or its isolation
1505
+ // controls. Do not enable it for secure mode without explicit user review.
1297
1506
  function createArtifactGraphGuard(scope, configuration, role, reader, originalWorker) {
1298
1507
  const files = runtimeFileMap(configuration);
1299
1508
  const edges = configuration.runtime.edges;
@@ -1356,7 +1565,7 @@ function createArtifactGraphGuard(scope, configuration, role, reader, originalWo
1356
1565
  return true;
1357
1566
  }
1358
1567
 
1359
- const guard = Object.freeze({
1568
+ const guard = completeValue({
1360
1569
  protocol: "arcane-ai-browser-speech-artifact-graph-runtime/1",
1361
1570
 
1362
1571
  async dynamicImport(capability, modulePath, occurrence, specifier) {
@@ -1477,7 +1686,7 @@ function createArtifactGraphGuard(scope, configuration, role, reader, originalWo
1477
1686
  event.stopImmediatePropagation?.();
1478
1687
  const admitted = normalizeSpeechWorkerErrorEnvelope(event.data.error, role, "load");
1479
1688
  const failure = admitted
1480
- ? workerError(admitted.code, admitted.message, undefined, admitted.reason)
1689
+ ? workerError(admitted.code, admitted.message, admitted.cause, admitted.reason)
1481
1690
  : workerError(
1482
1691
  "ARCANE_AI_WORKER_MESSAGE_ERROR",
1483
1692
  "The authenticated artifact module Worker error envelope was rejected.",
@@ -1545,7 +1754,7 @@ function createArtifactGraphGuard(scope, configuration, role, reader, originalWo
1545
1754
  },
1546
1755
  });
1547
1756
 
1548
- return Object.freeze({
1757
+ return completeValue({
1549
1758
  guard,
1550
1759
  transformersCache: (() => {
1551
1760
  const edgesForTransformers = [...cacheOpens.values()].filter((edge) =>
@@ -1640,7 +1849,6 @@ function installStringTimerIsolation(scope, name) {
1640
1849
  function installArtifactGraphEnvironment(scope, configuration, role) {
1641
1850
  const originalFetch = scope.fetch?.bind(scope);
1642
1851
  const originalWorker = scope.Worker;
1643
- const strictSecurity = configuration.security?.secure === true;
1644
1852
  if (typeof originalFetch !== "function") {
1645
1853
  throw workerError(
1646
1854
  "ARCANE_AI_PROVIDER_UNAVAILABLE",
@@ -1667,120 +1875,18 @@ function installArtifactGraphEnvironment(scope, configuration, role) {
1667
1875
  );
1668
1876
  const restores = [];
1669
1877
  try {
1670
- if (strictSecurity) {
1671
- restores.push(installDynamicCodeConstructorIsolation());
1672
- restores.push(installStringTimerIsolation(scope, "setInterval"));
1673
- restores.push(installStringTimerIsolation(scope, "setTimeout"));
1674
- if ("indexedDB" in scope) {
1675
- restores.push(installScopeValue(
1676
- scope,
1677
- "indexedDB",
1678
- undefined,
1679
- "artifact-graph-indexeddb-isolation-unavailable",
1680
- ));
1681
- }
1682
- if (scope.navigator && "storage" in scope.navigator) {
1683
- restores.push(installObjectValue(
1684
- scope.navigator,
1685
- "storage",
1686
- undefined,
1687
- "WorkerNavigator.storage",
1688
- "artifact-graph-opfs-isolation-unavailable",
1689
- ));
1690
- }
1691
- }
1692
1878
  restores.push(installScopeValue(
1693
1879
  scope,
1694
1880
  GRAPH_GUARD_NAME,
1695
1881
  graphGuard.guard,
1696
1882
  "artifact-graph-guard-global-definition-rejected",
1697
1883
  ));
1698
- if (strictSecurity) {
1699
- restores.push(installScopeValue(
1700
- scope,
1701
- "fetch",
1702
- async function rejectUntransformedArtifactGraphFetch() {
1703
- throw workerError(
1704
- "ARCANE_AI_ARTIFACT_GRAPH_FETCH_EDGE_UNDECLARED",
1705
- "Artifact graph fetch must use its declared transformed edge.",
1706
- undefined,
1707
- "artifact-graph-fetch-guard-bypassed",
1708
- );
1709
- },
1710
- "artifact-graph-fetch-isolation-unavailable",
1711
- ));
1712
- const cacheStorage = Object.freeze({
1713
- async open() {
1714
- throw workerError(
1715
- "ARCANE_AI_ARTIFACT_GRAPH_CACHE_EDGE_UNDECLARED",
1716
- "Artifact graph CacheStorage.open must use its declared transformed edge.",
1717
- undefined,
1718
- "artifact-graph-cache-open-guard-bypassed",
1719
- );
1720
- },
1721
- async match() {
1722
- throw workerError(
1723
- "ARCANE_AI_ARTIFACT_GRAPH_CACHE_EDGE_UNDECLARED",
1724
- "Artifact graph CacheStorage.match requires a declared cache-open edge.",
1725
- undefined,
1726
- "artifact-graph-cache-match-guard-bypassed",
1727
- );
1728
- },
1729
- async has() {
1730
- return true;
1731
- },
1732
- async keys() {
1733
- return Object.freeze([]);
1734
- },
1735
- async delete() {
1736
- return false;
1737
- },
1738
- });
1739
- restores.push(installScopeValue(
1740
- scope,
1741
- "caches",
1742
- cacheStorage,
1743
- "artifact-graph-cache-isolation-unavailable",
1744
- ));
1745
-
1746
- const deniedCapabilities = [
1747
- "BroadcastChannel",
1748
- "EventSource",
1749
- "Function",
1750
- "RTCPeerConnection",
1751
- "ShadowRealm",
1752
- "SharedWorker",
1753
- "WebSocket",
1754
- "WebSocketStream",
1755
- "WebTransport",
1756
- "Worker",
1757
- "XMLHttpRequest",
1758
- "eval",
1759
- "importScripts",
1760
- ];
1761
- for (const name of deniedCapabilities) {
1762
- if (!(name in scope)) continue;
1763
- restores.push(installScopeValue(
1764
- scope,
1765
- name,
1766
- function rejectUndeclaredArtifactGraphCapability() {
1767
- throw workerError(
1768
- "ARCANE_AI_ARTIFACT_GRAPH_ISOLATION_UNAVAILABLE",
1769
- `The authenticated artifact graph denied raw ${name} access.`,
1770
- undefined,
1771
- `artifact-graph-${name.toLowerCase()}-capability-undeclared`,
1772
- );
1773
- },
1774
- `artifact-graph-${name.toLowerCase()}-isolation-unavailable`,
1775
- ));
1776
- }
1777
- }
1778
1884
  } catch (error) {
1779
1885
  restoreScopeValues(restores);
1780
1886
  graphGuard.cleanup();
1781
1887
  throw error;
1782
1888
  }
1783
- return Object.freeze({
1889
+ return completeValue({
1784
1890
  cache: graphGuard.transformersCache,
1785
1891
  cleanup() {
1786
1892
  graphGuard.cleanup();
@@ -1789,6 +1895,300 @@ function installArtifactGraphEnvironment(scope, configuration, role) {
1789
1895
  });
1790
1896
  }
1791
1897
 
1898
+ function ordinaryRequestUrl(value, scope, base = scope.location?.href) {
1899
+ const input = typeof value === "string" || value instanceof URL
1900
+ ? String(value)
1901
+ : value?.url;
1902
+ if (typeof input !== "string" || input.length < 1) return null;
1903
+ try {
1904
+ return new URL(input, base).href;
1905
+ } catch {
1906
+ return null;
1907
+ }
1908
+ }
1909
+
1910
+ function isBareModuleSpecifier(value) {
1911
+ return typeof value === "string"
1912
+ && !value.startsWith("./")
1913
+ && !value.startsWith("../")
1914
+ && !value.startsWith("/")
1915
+ && !/^[A-Za-z][A-Za-z\d+.-]*:/u.test(value);
1916
+ }
1917
+
1918
+ function createOrdinaryRoutes(scope, configuration) {
1919
+ const files = [
1920
+ ...configuration.runtime.files,
1921
+ ...configuration.model.files,
1922
+ ];
1923
+ const filesByPath = new Map(files.map((file) => [file.path, file]));
1924
+ const routes = new Map();
1925
+ const ambiguous = new Set();
1926
+
1927
+ function add(route, file) {
1928
+ const absolute = ordinaryRequestUrl(route, scope);
1929
+ if (!absolute || ambiguous.has(absolute)) return;
1930
+ const existing = routes.get(absolute);
1931
+ if (existing && existing.path !== file.path) {
1932
+ routes.delete(absolute);
1933
+ ambiguous.add(absolute);
1934
+ return;
1935
+ }
1936
+ routes.set(absolute, file);
1937
+ }
1938
+
1939
+ for (const file of files) {
1940
+ add(file.sourceUrl, file);
1941
+ add(file.moduleUrl, file);
1942
+ for (const route of file.runtimeRequestUrls ?? []) add(route, file);
1943
+ }
1944
+ return completeValue({ files, filesByPath, routes });
1945
+ }
1946
+
1947
+ function createOrdinaryRouteReader(
1948
+ scope,
1949
+ configuration,
1950
+ originalFetch,
1951
+ originalCaches,
1952
+ ) {
1953
+ const routeTable = createOrdinaryRoutes(scope, configuration);
1954
+ const nativeCaches = new Map();
1955
+ const RequestConstructor = scope.Request ?? globalThis.Request;
1956
+
1957
+ function sourceBase(modulePath) {
1958
+ return routeTable.filesByPath.get(modulePath)?.sourceUrl ?? scope.location?.href;
1959
+ }
1960
+
1961
+ function nativeInput(input, modulePath) {
1962
+ if (typeof input !== "string" && !(input instanceof URL)) return input;
1963
+ return ordinaryRequestUrl(input, scope, sourceBase(modulePath)) ?? input;
1964
+ }
1965
+
1966
+ function resolve(input, modulePath) {
1967
+ const absolute = ordinaryRequestUrl(input, scope, sourceBase(modulePath));
1968
+ const file = absolute ? routeTable.routes.get(absolute) : null;
1969
+ return file ? completeValue({ absolute, file }) : null;
1970
+ }
1971
+
1972
+ function responseFor(resolution, input, init) {
1973
+ const mappedInput = typeof RequestConstructor === "function"
1974
+ && input instanceof RequestConstructor
1975
+ ? new RequestConstructor(resolution.file.moduleUrl, input)
1976
+ : resolution.file.moduleUrl;
1977
+ return originalFetch(mappedInput, init);
1978
+ }
1979
+
1980
+ async function nativeCache(name) {
1981
+ if (!originalCaches || typeof originalCaches.open !== "function") return null;
1982
+ if (!nativeCaches.has(name)) {
1983
+ nativeCaches.set(name, Promise.resolve(originalCaches.open.call(originalCaches, name)));
1984
+ }
1985
+ return nativeCaches.get(name);
1986
+ }
1987
+
1988
+ function cacheForName(name, modulePath) {
1989
+ return completeValue({
1990
+ async match(input, options) {
1991
+ const resolution = resolve(input, modulePath);
1992
+ if (resolution) return responseFor(resolution, input);
1993
+ const cache = await nativeCache(name);
1994
+ return cache?.match(nativeInput(input, modulePath), options);
1995
+ },
1996
+ async put(input, response) {
1997
+ const cache = await nativeCache(name);
1998
+ if (!cache) throw new TypeError("Browser CacheStorage is unavailable.");
1999
+ return cache.put(nativeInput(input, modulePath), response);
2000
+ },
2001
+ async add(input) {
2002
+ const cache = await nativeCache(name);
2003
+ if (!cache) throw new TypeError("Browser CacheStorage is unavailable.");
2004
+ return cache.add(nativeInput(input, modulePath));
2005
+ },
2006
+ async addAll(inputs) {
2007
+ const cache = await nativeCache(name);
2008
+ if (!cache) throw new TypeError("Browser CacheStorage is unavailable.");
2009
+ return cache.addAll(Array.from(inputs, (input) => nativeInput(input, modulePath)));
2010
+ },
2011
+ async delete(input, options) {
2012
+ const cache = await nativeCache(name);
2013
+ return cache ? cache.delete(nativeInput(input, modulePath), options) : false;
2014
+ },
2015
+ async keys(input, options) {
2016
+ const cache = await nativeCache(name);
2017
+ if (!cache) return [];
2018
+ return input === undefined
2019
+ ? cache.keys()
2020
+ : cache.keys(nativeInput(input, modulePath), options);
2021
+ },
2022
+ });
2023
+ }
2024
+
2025
+ return completeValue({ cacheForName, nativeInput, resolve, responseFor });
2026
+ }
2027
+
2028
+ function createOrdinaryArtifactModuleRouter(
2029
+ scope,
2030
+ configuration,
2031
+ role,
2032
+ reader,
2033
+ originalFetch,
2034
+ originalWorker,
2035
+ ) {
2036
+ const nestedWorkers = new Set();
2037
+ const router = completeValue({
2038
+ async dynamicImport(modulePath, specifier) {
2039
+ const resolution = isBareModuleSpecifier(specifier)
2040
+ ? null
2041
+ : reader.resolve(specifier, modulePath);
2042
+ const target = resolution?.file.moduleUrl
2043
+ ?? (isBareModuleSpecifier(specifier)
2044
+ ? specifier
2045
+ : reader.nativeInput(specifier, modulePath));
2046
+ return import(target);
2047
+ },
2048
+
2049
+ fetch(modulePath, input, init) {
2050
+ const resolution = reader.resolve(input, modulePath);
2051
+ return resolution
2052
+ ? reader.responseFor(resolution, input, init)
2053
+ : originalFetch(reader.nativeInput(input, modulePath), init);
2054
+ },
2055
+
2056
+ openCache(modulePath, name) {
2057
+ return Promise.resolve(reader.cacheForName(name, modulePath));
2058
+ },
2059
+
2060
+ createWorker(modulePath, specifier, options = {}) {
2061
+ if (typeof originalWorker !== "function") {
2062
+ throw workerError(
2063
+ "ARCANE_AI_PROVIDER_UNAVAILABLE",
2064
+ "Nested browser Workers are unavailable.",
2065
+ undefined,
2066
+ "speech-module-worker-constructor-unavailable",
2067
+ );
2068
+ }
2069
+ const resolution = reader.resolve(specifier, modulePath);
2070
+ if (!resolution) {
2071
+ return new originalWorker(reader.nativeInput(specifier, modulePath), options);
2072
+ }
2073
+ const workerOptions = options && typeof options === "object"
2074
+ ? { ...options, type: "module" }
2075
+ : { type: "module" };
2076
+ const worker = new originalWorker(nestedWorkerUrl(role), workerOptions);
2077
+ nestedWorkers.add(worker);
2078
+ const onBootstrapMessage = (event) => {
2079
+ if (event.data?.protocol !== NESTED_WORKER_PROTOCOL
2080
+ || event.data?.event !== "artifact-module-worker-bootstrap-rejected") return;
2081
+ event.stopImmediatePropagation?.();
2082
+ const admitted = normalizeSpeechWorkerErrorEnvelope(event.data.error, role, "load");
2083
+ const failure = admitted
2084
+ ? workerError(admitted.code, admitted.message, admitted.cause, admitted.reason)
2085
+ : workerError(
2086
+ "ARCANE_AI_WORKER_MESSAGE_ERROR",
2087
+ "The artifact module Worker error envelope was rejected.",
2088
+ undefined,
2089
+ "speech-module-worker-error-envelope-rejected",
2090
+ );
2091
+ worker.dispatchEvent?.(nestedWorkerFailureEvent(scope, failure));
2092
+ };
2093
+ worker.addEventListener?.("message", onBootstrapMessage);
2094
+ try {
2095
+ worker.postMessage({
2096
+ protocol: NESTED_WORKER_PROTOCOL,
2097
+ op: "initialize-artifact-module-worker",
2098
+ role,
2099
+ targetPath: resolution.file.path,
2100
+ configuration,
2101
+ });
2102
+ } catch (error) {
2103
+ nestedWorkers.delete(worker);
2104
+ worker.terminate();
2105
+ throw workerError(
2106
+ "ARCANE_AI_WORKER_MESSAGE_ERROR",
2107
+ "The artifact module Worker initialization message was rejected.",
2108
+ error,
2109
+ "speech-module-worker-initialization-message-rejected",
2110
+ );
2111
+ }
2112
+ return worker;
2113
+ },
2114
+ });
2115
+ return completeValue({
2116
+ router,
2117
+ transformersCache: reader.cacheForName("transformers-cache", null),
2118
+ cleanup() {
2119
+ for (const worker of nestedWorkers) {
2120
+ try {
2121
+ worker.terminate();
2122
+ } catch {
2123
+ // The owning speech Worker is already being torn down.
2124
+ }
2125
+ }
2126
+ nestedWorkers.clear();
2127
+ },
2128
+ });
2129
+ }
2130
+
2131
+ function installOrdinaryArtifactModuleRouter(scope, configuration, role) {
2132
+ const originalFetch = scope.fetch?.bind(scope);
2133
+ const originalWorker = scope.Worker;
2134
+ const originalCaches = scope.caches;
2135
+ if (typeof originalFetch !== "function") {
2136
+ throw workerError(
2137
+ "ARCANE_AI_PROVIDER_UNAVAILABLE",
2138
+ "Browser fetch is unavailable in the speech Worker.",
2139
+ undefined,
2140
+ "speech-worker-fetch-unavailable",
2141
+ );
2142
+ }
2143
+ const reader = createOrdinaryRouteReader(
2144
+ scope,
2145
+ configuration,
2146
+ originalFetch,
2147
+ originalCaches,
2148
+ );
2149
+ const moduleRouter = createOrdinaryArtifactModuleRouter(
2150
+ scope,
2151
+ configuration,
2152
+ role,
2153
+ reader,
2154
+ originalFetch,
2155
+ originalWorker,
2156
+ );
2157
+ const hadOwn = Object.prototype.hasOwnProperty.call(scope, MODULE_ROUTER_NAME);
2158
+ const previous = scope[MODULE_ROUTER_NAME];
2159
+ try {
2160
+ scope[MODULE_ROUTER_NAME] = moduleRouter.router;
2161
+ if (scope[MODULE_ROUTER_NAME] !== moduleRouter.router) {
2162
+ Object.defineProperty(scope, MODULE_ROUTER_NAME, {
2163
+ configurable: true,
2164
+ enumerable: true,
2165
+ writable: true,
2166
+ value: moduleRouter.router,
2167
+ });
2168
+ }
2169
+ } catch (error) {
2170
+ moduleRouter.cleanup();
2171
+ throw workerError(
2172
+ "ARCANE_AI_PROVIDER_UNAVAILABLE",
2173
+ "The speech Worker cannot install the artifact module router.",
2174
+ error,
2175
+ "speech-module-router-unavailable",
2176
+ );
2177
+ }
2178
+ return completeValue({
2179
+ cache: moduleRouter.transformersCache,
2180
+ cleanup() {
2181
+ moduleRouter.cleanup();
2182
+ try {
2183
+ if (hadOwn) scope[MODULE_ROUTER_NAME] = previous;
2184
+ else delete scope[MODULE_ROUTER_NAME];
2185
+ } catch {
2186
+ // Worker teardown releases the remaining module router reference.
2187
+ }
2188
+ },
2189
+ });
2190
+ }
2191
+
1792
2192
  function assignSetting(object, name, value, cleanup, {
1793
2193
  allowCreate = false,
1794
2194
  assignmentRejectedReason,
@@ -1846,14 +2246,6 @@ function assignSetting(object, name, value, cleanup, {
1846
2246
 
1847
2247
  function configuredWasmPaths(configuration) {
1848
2248
  if (configuration.runtime.wasmPaths !== undefined) {
1849
- if (configuration.security?.secure === true) {
1850
- throw workerError(
1851
- "ARCANE_AI_INVALID_REQUEST",
1852
- "Secure browser speech cannot use remote wasmPaths.",
1853
- undefined,
1854
- "speech-worker-secure-remote-wasm-paths-rejected",
1855
- );
1856
- }
1857
2249
  return configuration.runtime.wasmPaths;
1858
2250
  }
1859
2251
  const byPath = new Map(configuration.runtime.files.map((file) => [file.path, file]));
@@ -1874,12 +2266,11 @@ function configuredWasmPaths(configuration) {
1874
2266
  "artifact-graph-onnx-wasm-pair-not-materialized",
1875
2267
  );
1876
2268
  }
1877
- return Object.freeze({ mjs: mjs.moduleUrl, wasm: wasm.moduleUrl });
2269
+ return completeValue({ mjs: mjs.moduleUrl, wasm: wasm.moduleUrl });
1878
2270
  }
1879
2271
 
1880
2272
  function configureRuntimeNamespace(namespace, configuration, role, cache) {
1881
2273
  const cleanup = [];
1882
- const strictSecurity = configuration.security?.secure === true;
1883
2274
  const restoreSettings = () => {
1884
2275
  for (const restore of cleanup.splice(0).reverse()) {
1885
2276
  try {
@@ -1939,24 +2330,6 @@ function configureRuntimeNamespace(namespace, configuration, role, cache) {
1939
2330
  assignmentRejectedReason: "transformers-env-allow-remote-models-assignment-rejected",
1940
2331
  unavailableReason: "transformers-env-allow-remote-models-unavailable",
1941
2332
  });
1942
- if (strictSecurity) {
1943
- assignSetting(env, "useBrowserCache", false, cleanup, {
1944
- assignmentRejectedReason: "transformers-env-browser-cache-assignment-rejected",
1945
- unavailableReason: "transformers-env-browser-cache-unavailable",
1946
- });
1947
- assignSetting(env, "useFSCache", false, cleanup, {
1948
- assignmentRejectedReason: "transformers-env-fs-cache-assignment-rejected",
1949
- unavailableReason: "transformers-env-fs-cache-unavailable",
1950
- });
1951
- assignSetting(env, "useCustomCache", cache !== null, cleanup, {
1952
- assignmentRejectedReason: "transformers-env-custom-cache-toggle-assignment-rejected",
1953
- unavailableReason: "transformers-env-custom-cache-toggle-unavailable",
1954
- });
1955
- assignSetting(env, "customCache", cache, cleanup, {
1956
- assignmentRejectedReason: "transformers-env-custom-cache-assignment-rejected",
1957
- unavailableReason: "transformers-env-custom-cache-unavailable",
1958
- });
1959
- }
1960
2333
  if (paths) {
1961
2334
  assignSetting(
1962
2335
  wasm,
@@ -1990,39 +2363,6 @@ function configureRuntimeNamespace(namespace, configuration, role, cache) {
1990
2363
  return restoreSettings;
1991
2364
  }
1992
2365
 
1993
- function workerProgress(send, role, requestId, phase, completed = 0, total = null, unit = "items") {
1994
- send({
1995
- protocol: SPEECH_WORKER_PROTOCOL,
1996
- event: "progress",
1997
- requestId,
1998
- progress: Object.freeze({
1999
- phase,
2000
- completed,
2001
- total,
2002
- unit,
2003
- heartbeat: true,
2004
- }),
2005
- }, []);
2006
- }
2007
-
2008
- function upstreamProgress(send, role, requestId) {
2009
- return function reportSpeechModelProgress(update = {}) {
2010
- const completed = Number.isFinite(update.loaded)
2011
- ? update.loaded
2012
- : Number.isFinite(update.progress) ? update.progress : 0;
2013
- const total = Number.isFinite(update.total) ? update.total : null;
2014
- workerProgress(
2015
- send,
2016
- role,
2017
- requestId,
2018
- `${role}-model-load-progress`,
2019
- completed,
2020
- total,
2021
- Number.isFinite(update.loaded) ? "bytes" : "items",
2022
- );
2023
- };
2024
- }
2025
-
2026
2366
  async function disposeEngine(engine) {
2027
2367
  if (!engine) return;
2028
2368
  if (typeof engine.dispose === "function") {
@@ -2067,12 +2407,12 @@ async function createWhisperEngine(namespace, configuration, signal, report) {
2067
2407
  }
2068
2408
  throw error;
2069
2409
  }
2070
- return Object.freeze({
2410
+ return completeValue({
2071
2411
  async transcribe(input, { signal: requestSignal } = {}) {
2072
2412
  throwIfAborted(requestSignal, "stt-transcription-cancelled");
2073
2413
  const output = await transcriber(input.audio, { signal: requestSignal });
2074
2414
  throwIfAborted(requestSignal, "stt-transcription-cancelled");
2075
- return Object.freeze({ text: String(output?.text ?? "").trim() });
2415
+ return completeValue({ text: String(output?.text ?? "") });
2076
2416
  },
2077
2417
  dispose: () => disposeEngine(transcriber),
2078
2418
  });
@@ -2107,7 +2447,7 @@ async function createKokoroEngine(namespace, configuration, signal, report) {
2107
2447
  }
2108
2448
  throw error;
2109
2449
  }
2110
- return Object.freeze({
2450
+ return completeValue({
2111
2451
  async synthesize(input, { signal: requestSignal } = {}) {
2112
2452
  throwIfAborted(requestSignal, "tts-synthesis-cancelled");
2113
2453
  const output = await synthesizer.generate(input.text, {
@@ -2119,7 +2459,7 @@ async function createKokoroEngine(namespace, configuration, signal, report) {
2119
2459
  const audio = output?.audio instanceof Float32Array
2120
2460
  ? output.audio
2121
2461
  : new Float32Array(output?.audio ?? []);
2122
- return Object.freeze({
2462
+ return completeValue({
2123
2463
  audio,
2124
2464
  sampleRate: output?.sampling_rate,
2125
2465
  voice: input.voice,
@@ -2157,9 +2497,9 @@ function validateInput(role, payload, configuration) {
2157
2497
  "stt-transcription-sample-rate-mismatch",
2158
2498
  );
2159
2499
  }
2160
- return Object.freeze({ audio: payload.audio, sampleRate: inputSampleRate });
2500
+ return completeValue({ audio: payload.audio, sampleRate: inputSampleRate });
2161
2501
  }
2162
- const text = requiredText(payload?.text, "Kokoro text", "tts-synthesis-text-empty");
2502
+ const text = requiredContent(payload?.text, "Kokoro text", "tts-synthesis-text-empty");
2163
2503
  const voice = requiredText(
2164
2504
  payload?.voice ?? configuration.model.defaultVoice,
2165
2505
  "Kokoro voice",
@@ -2175,15 +2515,15 @@ function validateInput(role, payload, configuration) {
2175
2515
  );
2176
2516
  }
2177
2517
  const speed = payload?.speed ?? 1;
2178
- if (!Number.isFinite(speed) || speed <= 0 || speed > 4) {
2518
+ if (!Number.isFinite(speed) || speed <= 0) {
2179
2519
  throw workerError(
2180
2520
  "ARCANE_AI_INVALID_REQUEST",
2181
- "Kokoro speed must be greater than 0 and at most 4.",
2521
+ "Kokoro speed must be greater than 0.",
2182
2522
  undefined,
2183
- "tts-synthesis-speed-out-of-range",
2523
+ "tts-synthesis-speed-not-positive",
2184
2524
  );
2185
2525
  }
2186
- return Object.freeze({ text, voice, speed });
2526
+ return completeValue({ text, voice, speed });
2187
2527
  }
2188
2528
 
2189
2529
  function validateResult(role, result, configuration) {
@@ -2196,7 +2536,7 @@ function validateResult(role, result, configuration) {
2196
2536
  "stt-transcription-result-text-not-string",
2197
2537
  );
2198
2538
  }
2199
- return Object.freeze({ text: result.text.trim() });
2539
+ return completeValue({ text: result.text });
2200
2540
  }
2201
2541
  const outputSampleRate = requiredSampleRate(
2202
2542
  configuration.model.outputSampleRate,
@@ -2229,7 +2569,7 @@ function validateResult(role, result, configuration) {
2229
2569
  );
2230
2570
  }
2231
2571
  }
2232
- return Object.freeze({
2572
+ return completeValue({
2233
2573
  audio: result.audio,
2234
2574
  sampleRate: outputSampleRate,
2235
2575
  voice: result.voice,
@@ -2254,16 +2594,7 @@ export function createSpeechWorkerRuntime({ role, scope = globalThis, send } = {
2254
2594
 
2255
2595
  function status() {
2256
2596
  const state = disposed ? "disposed" : engine ? "ready" : "unloaded";
2257
- const security = configuration?.security
2258
- ? Object.freeze({
2259
- secure: configuration.security.secure === true,
2260
- checks: Object.freeze({
2261
- byteLength: configuration.security.checks?.byteLength === true,
2262
- sha256: configuration.security.checks?.sha256 === true,
2263
- }),
2264
- })
2265
- : null;
2266
- return Object.freeze({
2597
+ return completeValue({
2267
2598
  state,
2268
2599
  lifecycleStatus: `${role}-worker-${state}`,
2269
2600
  lifecycleReason,
@@ -2271,9 +2602,6 @@ export function createSpeechWorkerRuntime({ role, scope = globalThis, send } = {
2271
2602
  loaded: engine !== null,
2272
2603
  busy: operations.size > 0,
2273
2604
  activeOperation: operations.values().next().value?.publicOperation ?? null,
2274
- security,
2275
- artifactGraphId: configuration?.runtime?.artifactGraphId ?? null,
2276
- artifactGraphAdmission: configuration?.runtime?.artifactGraphAdmission ?? null,
2277
2605
  });
2278
2606
  }
2279
2607
 
@@ -2293,33 +2621,14 @@ export function createSpeechWorkerRuntime({ role, scope = globalThis, send } = {
2293
2621
  configuration = validateConfiguration(request.payload?.configuration, role);
2294
2622
  const entry = configuration.runtime.files.find((file) =>
2295
2623
  file.path === configuration.runtime.entry);
2296
- if (graphConfiguration(configuration) && configuration.security?.secure === true) {
2297
- environment = installArtifactGraphEnvironment(scope, configuration, role);
2298
- } else if (configuration.security?.secure === true) {
2299
- const legacyFetch = installLegacyAuthorizedFetch(scope, configuration);
2300
- try {
2301
- const restoreCaches = installDeniedCacheIsolation(scope);
2302
- environment = Object.freeze({
2303
- cache: null,
2304
- cleanup() {
2305
- try {
2306
- restoreCaches();
2307
- } finally {
2308
- legacyFetch.cleanup();
2309
- }
2310
- },
2311
- });
2312
- } catch (error) {
2313
- legacyFetch.cleanup();
2314
- throw error;
2315
- }
2624
+ if (graphConfiguration(configuration)) {
2625
+ environment = installOrdinaryArtifactModuleRouter(scope, configuration, role);
2316
2626
  } else {
2317
- environment = Object.freeze({
2627
+ environment = completeValue({
2318
2628
  cache: null,
2319
2629
  cleanup() {},
2320
2630
  });
2321
2631
  }
2322
- workerProgress(send, role, request.id, `${role}-runtime-import-started`);
2323
2632
  loadFailureReason = `${role}-worker-runtime-import-rejected`;
2324
2633
  const namespace = await import(entry.moduleUrl);
2325
2634
  throwIfAborted(signal, `${role}-load-cancelled`);
@@ -2329,14 +2638,12 @@ export function createSpeechWorkerRuntime({ role, scope = globalThis, send } = {
2329
2638
  role,
2330
2639
  environment.cache,
2331
2640
  );
2332
- workerProgress(send, role, request.id, `${role}-model-load-started`);
2333
2641
  loadFailureReason = `${role}-worker-model-load-rejected`;
2334
- const report = upstreamProgress(send, role, request.id);
2642
+ const report = () => undefined;
2335
2643
  engine = role === "stt"
2336
2644
  ? await createWhisperEngine(namespace, configuration, signal, report)
2337
2645
  : await createKokoroEngine(namespace, configuration, signal, report);
2338
2646
  lifecycleReason = `${role}-load-completed`;
2339
- workerProgress(send, role, request.id, `${role}-provider-ready`, 1, 1);
2340
2647
  return status();
2341
2648
  } catch (error) {
2342
2649
  const failure = admitWorkerFailure(
@@ -2476,12 +2783,15 @@ export function createSpeechWorkerRuntime({ role, scope = globalThis, send } = {
2476
2783
  id: request.id,
2477
2784
  ok: true,
2478
2785
  result: result ?? null,
2479
- }, collectSpeechTransferables(result)), (error) => send({
2480
- protocol: SPEECH_WORKER_PROTOCOL,
2481
- id: request.id,
2482
- ok: false,
2483
- error: serializedError(error, role, op),
2484
- }, []));
2786
+ }, collectSpeechTransferables(result)), (error) => {
2787
+ const response = {
2788
+ protocol: SPEECH_WORKER_PROTOCOL,
2789
+ id: request.id,
2790
+ ok: false,
2791
+ error: null,
2792
+ };
2793
+ sendSerializedError(send, response, error, role, op, scope);
2794
+ });
2485
2795
  }
2486
2796
 
2487
2797
  function handleMessage(request) {
@@ -2507,7 +2817,7 @@ export function createSpeechWorkerRuntime({ role, scope = globalThis, send } = {
2507
2817
  if (op === "cancel") {
2508
2818
  const target = operations.get(request.payload?.targetId);
2509
2819
  target?.controller.abort(operationReason(role, target.op, "cancelled"));
2510
- const result = Promise.resolve(Object.freeze({
2820
+ const result = Promise.resolve(completeValue({
2511
2821
  cancelled: Boolean(target),
2512
2822
  reason: target
2513
2823
  ? operationReason(role, target.op, "cancelled")
@@ -2532,24 +2842,14 @@ export function createSpeechWorkerRuntime({ role, scope = globalThis, send } = {
2532
2842
  return operation;
2533
2843
  }
2534
2844
 
2535
- return Object.freeze({ handleMessage, status });
2536
- }
2537
-
2538
- function privatePort(value) {
2539
- return value
2540
- && typeof value.postMessage === "function"
2541
- && typeof value.addEventListener === "function"
2542
- ? value
2543
- : null;
2845
+ return completeValue({ handleMessage, status });
2544
2846
  }
2545
2847
 
2546
2848
  export function installBrowserSpeechWorker(role, scope = globalThis) {
2547
- let transport = scope;
2548
- let transportMode = null;
2549
2849
  const runtime = createSpeechWorkerRuntime({
2550
2850
  role,
2551
2851
  scope,
2552
- send: (message, transfers) => transport.postMessage(message, transfers),
2852
+ send: (message, transfers) => scope.postMessage(message, transfers),
2553
2853
  });
2554
2854
 
2555
2855
  function receive(request) {
@@ -2557,36 +2857,6 @@ export function installBrowserSpeechWorker(role, scope = globalThis) {
2557
2857
  }
2558
2858
 
2559
2859
  scope.addEventListener("message", (event) => {
2560
- if (transportMode === "private-message-port") return;
2561
- const requestedPort = privatePort(event.data?.privatePort);
2562
- const isGraphLoad = event.data?.op === "load"
2563
- && graphConfiguration(event.data?.payload?.configuration);
2564
- if (requestedPort) {
2565
- if (!isGraphLoad || transportMode !== null) return;
2566
- transportMode = "private-message-port";
2567
- transport = requestedPort;
2568
- requestedPort.addEventListener("message", (portEvent) => receive(portEvent.data));
2569
- requestedPort.start?.();
2570
- const { privatePort: ignored, ...request } = event.data;
2571
- void ignored;
2572
- receive(request);
2573
- return;
2574
- }
2575
- if (isGraphLoad) {
2576
- scope.postMessage({
2577
- protocol: SPEECH_WORKER_PROTOCOL,
2578
- id: event.data.id,
2579
- ok: false,
2580
- error: serializedError(workerError(
2581
- "ARCANE_AI_ARTIFACT_GRAPH_ISOLATION_UNAVAILABLE",
2582
- "Authenticated artifact graph loading requires a private MessagePort.",
2583
- undefined,
2584
- "artifact-graph-private-message-port-missing",
2585
- ), role, "load"),
2586
- });
2587
- return;
2588
- }
2589
- transportMode ??= "worker-global-message";
2590
2860
  receive(event.data);
2591
2861
  });
2592
2862
  return runtime;
@@ -2613,7 +2883,7 @@ export function installBrowserSpeechArtifactModuleWorker(role, scope = globalThi
2613
2883
  }
2614
2884
  const request = event.data;
2615
2885
  if (request?.protocol !== NESTED_WORKER_PROTOCOL
2616
- || request.op !== "initialize-authenticated-artifact-module-worker"
2886
+ || request.op !== "initialize-artifact-module-worker"
2617
2887
  || request.role !== role) return;
2618
2888
  initializing = true;
2619
2889
  void (async () => {
@@ -2630,7 +2900,7 @@ export function installBrowserSpeechArtifactModuleWorker(role, scope = globalThi
2630
2900
  "artifact-graph-module-worker-target-not-materialized",
2631
2901
  );
2632
2902
  }
2633
- environment = installArtifactGraphEnvironment(scope, configuration, role);
2903
+ environment = installOrdinaryArtifactModuleRouter(scope, configuration, role);
2634
2904
  await import(target.moduleUrl);
2635
2905
  scope.removeEventListener("message", bootstrap);
2636
2906
  await new Promise((resolve) => queueMicrotask(resolve));
@@ -2641,17 +2911,27 @@ export function installBrowserSpeechArtifactModuleWorker(role, scope = globalThi
2641
2911
  } catch {
2642
2912
  // Preserve the exact nested Worker bootstrap failure.
2643
2913
  }
2644
- scope.postMessage({
2645
- protocol: NESTED_WORKER_PROTOCOL,
2646
- event: "artifact-module-worker-bootstrap-rejected",
2647
- error: serializedError(error, role, "load"),
2648
- });
2649
- scope.close?.();
2914
+ try {
2915
+ sendSerializedError(
2916
+ (message, transfers) => scope.postMessage(message, transfers),
2917
+ {
2918
+ protocol: NESTED_WORKER_PROTOCOL,
2919
+ event: "artifact-module-worker-bootstrap-rejected",
2920
+ error: null,
2921
+ },
2922
+ error,
2923
+ role,
2924
+ "load",
2925
+ scope,
2926
+ );
2927
+ } finally {
2928
+ scope.close?.();
2929
+ }
2650
2930
  }
2651
2931
  })();
2652
2932
  };
2653
2933
  scope.addEventListener("message", bootstrap);
2654
- return Object.freeze({
2934
+ return completeValue({
2655
2935
  protocol: NESTED_WORKER_PROTOCOL,
2656
2936
  role,
2657
2937
  lifecycleStatus: `${role}-artifact-module-worker-awaiting-initialization`,