arcane-os 0.5.8 → 0.5.9

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 (46) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +32 -27
  3. package/browser-runtime/ai/browser-speech-artifacts.mjs +23 -1683
  4. package/browser-runtime/ai/browser-speech-providers.mjs +353 -143
  5. package/browser-runtime/ai/browser-wasm-llm-provider.mjs +32 -324
  6. package/browser-runtime/ai/speech-worker-client.mjs +51 -14
  7. package/browser-runtime/ai/speech-worker-runtime.mjs +45 -1072
  8. package/browser-runtime/dependencies/strong-type/package.json +22 -23
  9. package/browser-runtime/event-manager.mjs +27 -41
  10. package/package.json +2 -3
  11. package/runtime/arcane/components/chat.html +1 -1
  12. package/runtime/arcane/components/speech.html +8 -38
  13. package/runtime/arcane/components/voice-transcription.html +1 -1
  14. package/runtime/arcane/css/theme.css +1 -1
  15. package/runtime/arcane/entities/Chat.js +12 -7
  16. package/runtime/arcane/modules/AI.js +506 -391
  17. package/runtime/arcane/modules/AIPreferenceTuple.js +1 -1
  18. package/runtime/arcane/modules/AIProviderRuntime.js +129 -68
  19. package/runtime/arcane/modules/AIRuntimeState.js +2 -18
  20. package/runtime/arcane/modules/BrowserTestSuite.js +2 -5
  21. package/runtime/arcane/modules/CalculatorEngine.js +0 -4
  22. package/runtime/arcane/modules/ChatRecords.js +169 -1
  23. package/runtime/arcane/modules/CommunicationHub.js +0 -19
  24. package/runtime/arcane/modules/ConfiguredAIChatSession.js +28 -25
  25. package/runtime/arcane/modules/DBOPFSDocumentLibrary.js +4 -5
  26. package/runtime/arcane/modules/DocumentLexicalSearch.js +1 -1
  27. package/runtime/arcane/modules/Errors.js +6 -19
  28. package/runtime/arcane/modules/Mail.js +1 -2
  29. package/runtime/arcane/modules/MailTransport.mjs +1 -3
  30. package/runtime/arcane/modules/OllamaModelIdentifier.js +1 -1
  31. package/runtime/arcane/modules/PersistentAIChatSession.js +5 -5
  32. package/runtime/arcane/modules/ScreenCapture.js +2 -4
  33. package/runtime/arcane/modules/SpeechPlayback.js +0 -27
  34. package/runtime/arcane/modules/WaitForComponent.js +0 -1
  35. package/src/app-descriptor.mjs +1 -1
  36. package/src/doctor.mjs +1 -3
  37. package/src/event-manager.mjs +27 -41
  38. package/src/import-map.mjs +1 -1
  39. package/src/index.mjs +2 -9
  40. package/src/installed-sdk-runtime.mjs +1 -11
  41. package/src/mail-api.mjs +0 -1
  42. package/src/native-provider-loader.mjs +0 -9
  43. package/src/scaffold.mjs +9 -21
  44. package/src/toolchain.mjs +5 -28
  45. package/src/workspace-runtime.mjs +0 -4
  46. package/src/workspace.mjs +2 -23
@@ -7,7 +7,6 @@ const communicationHubEvents={
7
7
  refreshCancelled:'communications-refresh-cancelled',
8
8
  refreshCompleted:'communications-refresh-completed',
9
9
  refreshFailed:'communications-refresh-failed',
10
- refreshLegacy:'communications-refresh',
11
10
  refreshPartiallyCompleted:'communications-refresh-partially-completed',
12
11
  refreshStarted:'communications-refresh-started'
13
12
  };
@@ -465,14 +464,6 @@ export default class CommunicationHub extends EventTarget{
465
464
  state,
466
465
  threadCount:threads.length
467
466
  };
468
- const legacyDetail={
469
- errors:[...returnedErrors],
470
- threads:[...returnedThreads]
471
- };
472
- const legacyPublicDetail={
473
- ...publicDetail,
474
- failures:publicDetail.failures.map(copyProviderFailure)
475
- };
476
467
  operation.terminal=true;
477
468
  this.#clearRefreshOperation(operation);
478
469
  this.#events.dispatch(
@@ -483,16 +474,6 @@ export default class CommunicationHub extends EventTarget{
483
474
  publicDetail
484
475
  }
485
476
  );
486
- if(!this.#events.disposed){
487
- this.#events.dispatch(
488
- communicationHubEvents.refreshLegacy,
489
- legacyDetail,
490
- {
491
- operationId:operation.operationId,
492
- publicDetail:legacyPublicDetail
493
- }
494
- );
495
- }
496
477
  return {threads:returnedThreads,errors:returnedErrors};
497
478
  }catch(error){
498
479
  if(operation.terminal){
@@ -1,3 +1,5 @@
1
+ import {recurringChatMessages} from './ChatRecords.js';
2
+
1
3
  const FORBIDDEN_REQUEST_FIELDS=new Set([
2
4
  'messages',
3
5
  'onChunk',
@@ -254,19 +256,20 @@ function cloneMessage(value){
254
256
  }
255
257
 
256
258
  function publicMessage(value){
257
- return {
258
- ...value,
259
- role:value.role,
260
- content:value.content,
261
- ...(Object.hasOwn(value,'reasoning_content')
262
- ?{reasoning_content:value.reasoning_content}
263
- :{}),
264
- ...(value.tool_calls?{tool_calls:value.tool_calls.map(call=>({
265
- ...call,
266
- function:{...call.function},
267
- }))}:{}),
268
- ...(value.tool_call_id?{tool_call_id:value.tool_call_id}:{}),
269
- };
259
+ const copy=cloneMessage(value);
260
+ if(copy.role==='tool'){
261
+ delete copy.message;
262
+ delete copy.name;
263
+ delete copy.status;
264
+ }
265
+ delete copy.memory_excluded;
266
+ delete copy.persistence_excluded;
267
+ delete copy.persistence_message;
268
+ delete copy.persistence_name;
269
+ delete copy.persistence_status;
270
+ delete copy.timestamp;
271
+ delete copy.ui_hidden;
272
+ return copy;
270
273
  }
271
274
 
272
275
  function normalizeInitialMessages(value){
@@ -493,12 +496,13 @@ function normalizeResponse(response){
493
496
  }
494
497
 
495
498
  /**
496
- * Maintains one complete, in-memory conversation through a configured chat provider.
499
+ * Maintains complete ordinary visible recurring conversation content plus only
500
+ * the active structural protocol required by a configured chat provider.
497
501
  *
498
502
  * This module performs no persistence, streaming, tool execution, rendering, or
499
503
  * provider selection. Applications own their prompt policy and may supply an
500
504
  * asynchronous contextBuilder that returns additional system text for each send.
501
- * Legacy response-length options are accepted without changing or shortening
505
+ * The response-length preference is accepted without changing or shortening
502
506
  * the caller's prompt. A configured chat function may return either the normalized
503
507
  * session response or a non-stream OpenAI-compatible completion.
504
508
  */
@@ -516,9 +520,6 @@ export default class ConfiguredAIChatSession{
516
520
  'chat',
517
521
  'contextBuilder',
518
522
  'initialMessages',
519
- 'maxContextCharacters',
520
- 'maxMessageCharacters',
521
- 'maxMessages',
522
523
  'request',
523
524
  'responseLength',
524
525
  'systemPrompt',
@@ -545,8 +546,10 @@ export default class ConfiguredAIChatSession{
545
546
  this.#request={...request};
546
547
  this.#systemPrompt=systemPrompt;
547
548
  const initialMessages=normalizeInitialMessages(options.initialMessages);
548
- const initialHistory=completeHistory(this.#systemPrompt,initialMessages);
549
- this.#conversation=initialHistory.filter(item=>item.role!=='system');
549
+ this.#conversation=recurringChatMessages(
550
+ initialMessages,
551
+ {settleCompleteToolTail:true},
552
+ );
550
553
  }
551
554
 
552
555
  history(){
@@ -732,11 +735,11 @@ export default class ConfiguredAIChatSession{
732
735
  const response=normalizeResponse(providerResponse);
733
736
  if(options.signal?.aborted) throw abortError();
734
737
  const retainedConversation=this.#conversation.map(cloneMessage);
735
- const committed=completeHistory(
736
- this.#systemPrompt,
737
- [...retainedConversation,...inputMessages,response.message],
738
- );
739
- const nextConversation=committed.filter(item=>item.role!=='system');
738
+ const nextConversation=recurringChatMessages([
739
+ ...retainedConversation,
740
+ ...inputMessages,
741
+ response.message,
742
+ ]);
740
743
  let settled=false;
741
744
  return {
742
745
  response,
@@ -732,7 +732,7 @@ class DBOPFSDocumentLibrary{
732
732
 
733
733
  async search(query,options={}){
734
734
  if(!isPlainRecord(options)) fail('Document search options must be a plain object.');
735
- assertKnownKeys(options,new Set(['kinds','limit','signal','tags']),'Document search options');
735
+ assertKnownKeys(options,new Set(['kinds','signal','tags']),'Document search options');
736
736
  if(!signalLike(options.signal)) fail('signal must be an AbortSignal.');
737
737
  const corpus=await this.#corpus(options.signal);
738
738
  const search=new DocumentLexicalSearch(corpus.records);
@@ -863,7 +863,7 @@ class DBOPFSDocumentLibrary{
863
863
 
864
864
  async buildContext(query,options={}){
865
865
  if(!isPlainRecord(options)) fail('Document context options must be a plain object.');
866
- assertKnownKeys(options,new Set(['limit','maxCharacters','maxDocumentCharacters','signal']),'Document context options');
866
+ assertKnownKeys(options,new Set(['signal']),'Document context options');
867
867
  if(!signalLike(options.signal)) fail('signal must be an AbortSignal.');
868
868
  const result=await this.search(query,{signal:options.signal});
869
869
  const preamble='DBOPFS DOCUMENT CONTEXT\n';
@@ -895,9 +895,8 @@ class DBOPFSDocumentLibrary{
895
895
 
896
896
  createContextBuilder(options={}){
897
897
  if(!isPlainRecord(options)) fail('Context builder options must be a plain object.');
898
- assertKnownKeys(options,new Set(['limit','maxCharacters','maxDocumentCharacters']),'Context builder options');
899
- const settings={...options};
900
- return async({input,signal}={})=>(await this.buildContext(input,{...settings,signal})).text;
898
+ assertKnownKeys(options,new Set(),'Context builder options');
899
+ return async({input,signal}={})=>(await this.buildContext(input,{signal})).text;
901
900
  }
902
901
  }
903
902
 
@@ -203,7 +203,7 @@ class DocumentLexicalSearch{
203
203
 
204
204
  search(query,options={}){
205
205
  if(!isPlainRecord(options)) fail('Search options must be a plain object.','DOCUMENT_SEARCH_INVALID_QUERY');
206
- const unknown=Object.keys(options).find(key=>!['kinds','limit','tags'].includes(key));
206
+ const unknown=Object.keys(options).find(key=>!['kinds','tags'].includes(key));
207
207
  if(unknown) fail(`Search options contain an unsupported field: ${unknown}.`,'DOCUMENT_SEARCH_INVALID_QUERY');
208
208
  return this.rank(query,{
209
209
  kinds:options.kinds,
@@ -129,15 +129,7 @@ export function normalizeRejectionEvent(event={},target=globalThis.window){
129
129
  };
130
130
  }
131
131
 
132
- /**
133
- * Return a fresh opaque occurrence identifier for legacy callers of the former
134
- * fingerprint helper. The incident is intentionally not read: identifiers do
135
- * not group, admit, or derive identity from error content.
136
- *
137
- * @param {Object} incident
138
- * @returns {string}
139
- */
140
- export function fingerprintIncident(_incident){
132
+ function nextErrorOccurrenceId(){
141
133
  runtimeOccurrenceSequence+=1;
142
134
  return `error-${RUNTIME_OCCURRENCE_PREFIX}-${runtimeOccurrenceSequence.toString(36)}`;
143
135
  }
@@ -517,9 +509,9 @@ class Errors {
517
509
  && storedRecord.occurrenceId.trim()
518
510
  )
519
511
  ? storedRecord.occurrenceId
520
- : fingerprintIncident(storedRecord.incident);
512
+ : nextErrorOccurrenceId();
521
513
  while(this.pending.has(occurrenceId)){
522
- occurrenceId=fingerprintIncident(storedRecord.incident);
514
+ occurrenceId=nextErrorOccurrenceId();
523
515
  }
524
516
  const record={
525
517
  capturedAt,
@@ -656,9 +648,9 @@ class Errors {
656
648
  return false;
657
649
  }
658
650
 
659
- let occurrenceId=fingerprintIncident(incident);
651
+ let occurrenceId=nextErrorOccurrenceId();
660
652
  while(this.pending.has(occurrenceId)){
661
- occurrenceId=fingerprintIncident(incident);
653
+ occurrenceId=nextErrorOccurrenceId();
662
654
  }
663
655
  const incidentKind=incident?.type==='unhandledrejection'
664
656
  ?'unhandled-promise-rejection'
@@ -675,12 +667,11 @@ class Errors {
675
667
  this.#operationSequence+=1;
676
668
  this.#events.dispatch(
677
669
  eventType,
678
- {id:occurrenceId,fingerprint:occurrenceId,code,kind:incidentKind,reason},
670
+ {id:occurrenceId,code,kind:incidentKind,reason},
679
671
  {
680
672
  operationId:`global-error-handler-${this.#events.instanceId}-${this.#operationSequence.toString(36)}`,
681
673
  publicDetail:{
682
674
  id:occurrenceId,
683
- fingerprint:occurrenceId,
684
675
  code,
685
676
  kind:incidentKind,
686
677
  reason
@@ -750,10 +741,6 @@ class Errors {
750
741
  return true;
751
742
  }
752
743
 
753
- flushFingerprint(fingerprint){
754
- return this.flushOccurrence(fingerprint);
755
- }
756
-
757
744
  buildNotification(record){
758
745
  const subject=record.incident?.type==='unhandledrejection'
759
746
  ? 'ARCANE JS UNHANDLED REJECTION'
@@ -1,7 +1,6 @@
1
1
  import {createArcaneEventSource} from 'arcane-os/event-manager';
2
2
  import MailOutbox from './MailOutbox.mjs';
3
3
  import {
4
- DEFAULT_MAIL_REQUEST_TIMEOUT_MS,
5
4
  sendMailReport,
6
5
  } from './MailTransport.mjs';
7
6
 
@@ -258,7 +257,7 @@ export function resolveMailConfig(
258
257
  : defaultMailEndpoint(location,supplied.baseDomain||declaredMailBaseDomain(document)),
259
258
  requestTimeout:Number.isFinite(supplied.requestTimeout)
260
259
  ? supplied.requestTimeout
261
- : DEFAULT_MAIL_REQUEST_TIMEOUT_MS,
260
+ : null,
262
261
  });
263
262
  }
264
263
 
@@ -1,5 +1,3 @@
1
- export const DEFAULT_MAIL_REQUEST_TIMEOUT_MS=null;
2
-
3
1
  const REPORT_KEY_PATTERN=/^[a-zA-Z0-9._:-]+$/;
4
2
  const REQUEST_ID_PATTERN=/^[a-zA-Z0-9-]+$/;
5
3
  const PROVIDER_ID_PATTERN=/^[a-zA-Z0-9._:-]+$/;
@@ -223,7 +221,7 @@ export async function sendMailReport({
223
221
  fetchImpl=globalThis.fetch,
224
222
  report,
225
223
  reportKey,
226
- requestTimeout=DEFAULT_MAIL_REQUEST_TIMEOUT_MS,
224
+ requestTimeout=null,
227
225
  serializedReport,
228
226
  signal,
229
227
  }){
@@ -10,7 +10,7 @@ export function normalizeOllamaModelIdentifier(value){
10
10
  if(typeof value!=='string'||value!==value.trim()){
11
11
  return null;
12
12
  }
13
- if(!OLLAMA_MODEL_IDENTIFIER.test(value)||value.toUpperCase()==='OPENAI'){
13
+ if(!OLLAMA_MODEL_IDENTIFIER.test(value)||value.toUpperCase()==='TWIN'){
14
14
  return null;
15
15
  }
16
16
  return value;
@@ -344,8 +344,8 @@ class PersistentAIChatSession{
344
344
  assertKnownKeys(
345
345
  options,
346
346
  new Set([
347
- 'ai','chat','chatEntity','chatFileName','contextBuilder','loadExisting','maxContextCharacters',
348
- 'maxMessageCharacters','maxMessages','memory','request','responseLength','systemPrompt'
347
+ 'ai','chat','chatEntity','chatFileName','contextBuilder','loadExisting','memory',
348
+ 'request','responseLength','systemPrompt'
349
349
  ]),
350
350
  'Persistent chat options',
351
351
  );
@@ -632,9 +632,9 @@ class PersistentAIChatSession{
632
632
  if(streamState) this.#activeStream=streamState;
633
633
  try{
634
634
  prepared=await this.#configured.prepare(
635
- settings.requestMessages.length===1
636
- ?settings.requestMessages[0]
637
- :settings.requestMessages,
635
+ settings.entityRequestMessages.length===1
636
+ ?settings.entityRequestMessages[0]
637
+ :settings.entityRequestMessages,
638
638
  {request:settings.request,signal:settings.signal},
639
639
  );
640
640
  }finally{
@@ -1197,11 +1197,9 @@ export default class ScreenCapture extends EventTarget{
1197
1197
  return operation.stopCallPromise;
1198
1198
  }
1199
1199
 
1200
- async prepare(stream,optionsValue={},legacyOptionsValue={}){
1200
+ async prepare(stream,optionsValue={}){
1201
1201
  this.#assertOpen();
1202
- const options=typeof optionsValue==='number'
1203
- ?optionsRecord(legacyOptionsValue,'Screen capture display options')
1204
- :optionsRecord(optionsValue,'Screen capture display options');
1202
+ const options=optionsRecord(optionsValue,'Screen capture display options');
1205
1203
  if(options.signal?.aborted)throw abortError(options.signal.reason);
1206
1204
  let video;
1207
1205
  try{
@@ -1,17 +1,5 @@
1
1
  import {createArcaneEventSource} from 'arcane-os/event-manager';
2
2
 
3
- const SPEECH_VOICE_OPTIONS=[
4
- {value:'alloy',label:'Alloy'},
5
- {value:'ash',label:'Ash'},
6
- {value:'ballad',label:'Ballad'},
7
- {value:'coral',label:'Coral'},
8
- {value:'echo',label:'Echo'},
9
- {value:'fable',label:'Fable'},
10
- {value:'nova',label:'Nova'},
11
- {value:'onyx',label:'Onyx'},
12
- {value:'sage',label:'Sage'},
13
- {value:'shimmer',label:'Shimmer'}
14
- ];
15
3
  const SUPERSEDED={superseded:true};
16
4
  const SPEECH_PLAYBACK_STATE_EVENT='speech-playback-state';
17
5
  const SPEECH_PLAYBACK_FAILURE_REASONS={
@@ -29,10 +17,6 @@ const WAV_AUDIO_CONTENT_TYPES=new Set([
29
17
  ]);
30
18
  const queuesBySpeechClient=new WeakMap();
31
19
 
32
- const SPEECH_VOICE_ALIASES=new Set(
33
- SPEECH_VOICE_OPTIONS.map(function voiceAlias(option){return option.value;})
34
- );
35
-
36
20
  function splitSpeechText(value=''){
37
21
  const text=String(value??'');
38
22
  return text.trim()?[text]:[];
@@ -333,7 +317,6 @@ class SpeechPlayback{
333
317
  voice=null,
334
318
  responseFormat=null,
335
319
  speed=1,
336
- onState=function noop(){},
337
320
  createObjectURL,
338
321
  revokeObjectURL,
339
322
  delay,
@@ -355,7 +338,6 @@ class SpeechPlayback{
355
338
  eventTypes:[SPEECH_PLAYBACK_STATE_EVENT]
356
339
  }
357
340
  );
358
- this.onState=onState;
359
341
  this.createObjectURL=createObjectURL||function createAudioURL(blob){return URL.createObjectURL(blob);};
360
342
  this.revokeObjectURL=revokeObjectURL||function revokeAudioURL(url){URL.revokeObjectURL(url);};
361
343
  this.delay=delay||function playbackDelay(duration,signal){
@@ -446,12 +428,6 @@ class SpeechPlayback{
446
428
  }
447
429
  );
448
430
  }
449
- try{
450
- this.onState(detail);
451
- }catch(error){
452
- if(typeof globalThis.reportError==='function')globalThis.reportError(error);
453
- else console.error(error);
454
- }
455
431
  return detail;
456
432
  }
457
433
 
@@ -860,14 +836,11 @@ class SpeechPlayback{
860
836
  this.audio.removeEventListener('error',this.boundError);
861
837
  this.destroyed=true;
862
838
  this.events.dispose();
863
- this.onState=function destroyedSpeechPlaybackStateObserver(){};
864
839
  return true;
865
840
  }
866
841
  }
867
842
 
868
843
  export {
869
- SPEECH_VOICE_ALIASES,
870
- SPEECH_VOICE_OPTIONS,
871
844
  SPEECH_PLAYBACK_STATE_EVENT,
872
845
  SpeechPlayback,
873
846
  splitSpeechText
@@ -301,7 +301,6 @@ function waitForComponent(element,options={}){
301
301
  if(componentCode){
302
302
  error.componentCode=componentCode;
303
303
  }
304
- error.compatibilityCode=componentCode||'COMPONENT_READY_FAILED';
305
304
  fail(
306
305
  defineComponentWaitError(
307
306
  error,
@@ -437,7 +437,7 @@ export async function loadAppDescriptor({workspaceRoot,appRoot,appId,packageMani
437
437
  const nativeDescriptor=isObject(registry?.apps?.[appId])?registry.apps[appId]:undefined;
438
438
  return completeValue({
439
439
  descriptor:synthesizedDescriptor(packageManifest,nativeDescriptor),
440
- source:nativeDescriptor?'legacy-registry':'legacy-package',
440
+ source:nativeDescriptor?'registry-projection':'package-projection',
441
441
  descriptorPath:null
442
442
  });
443
443
  }
package/src/doctor.mjs CHANGED
@@ -269,9 +269,7 @@ export async function runDoctor({
269
269
  checks.push(check(
270
270
  'workspace-runtime',
271
271
  'pass',
272
- layout==='integrated-legacy'
273
- ?'The legacy integrated Arcane runtime routes are valid.'
274
- :'The integrated physical browser-runtime routes are valid.',
272
+ 'The integrated physical browser-runtime routes are valid.',
275
273
  {details:{layout}}
276
274
  ));
277
275
  }
@@ -28,7 +28,6 @@ export const ARCANE_EVENT_AUTHORITY_KIND='arcane-event-authority';
28
28
  export const ARCANE_EVENT_SOURCE_KIND='arcane-event-source';
29
29
  export const ARCANE_EVENT_LISTENER_ERROR_EVENT='arcane.event.listener.error';
30
30
  export const ARCANE_EVENT_SOURCE_DISPOSED_EVENT='arcane.event.source.disposed';
31
- const ARCANE_EVENT_TARGET_COMPATIBILITY_SOURCE='event-target-compatibility';
32
31
  const ARCANE_EVENT_NAME_PATTERN=/^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)*$/u;
33
32
  const ARCANE_EVENT_CHANNEL_PREFIX='arcane.event.authority.internal:';
34
33
  const ARCANE_EVENT_PROJECTION_KEYS=[
@@ -36,23 +35,13 @@ const ARCANE_EVENT_PROJECTION_KEYS=[
36
35
  ];
37
36
  const ARCANE_EVENT_REQUIRED_AUTHORITY_API=[
38
37
  'on','once','off','reset','emit','instrument','forward','subscribe','createSource',
39
- 'projectDOMEvent','isOccurrence','addEventListener','removeEventListener','dispatchEvent'
38
+ 'projectDOMEvent','isOccurrence','addEventListener','removeEventListener'
40
39
  ];
41
40
  const EVENT_MANAGER_BUS_ON=Symbol('EventManager.busOn');
42
41
  const EVENT_MANAGER_BUS_OFF=Symbol('EventManager.busOff');
43
42
  const EVENT_MANAGER_DISPATCH=Symbol('EventManager.dispatch');
44
43
 
45
44
  const ARCANE_EVENT_ERRORS={
46
- ARCANE_EVENT_AUTHORITY_ACCESSOR_COLLISION:
47
- 'globalThis.arcaneEvents must be an own data property.',
48
- ARCANE_EVENT_AUTHORITY_VALUE_COLLISION:
49
- 'globalThis.arcaneEvents is occupied by an unbranded value.',
50
- ARCANE_EVENT_AUTHORITY_DESCRIPTOR_MISMATCH:
51
- 'The globalThis.arcaneEvents property, authority brand, or protocol descriptor is incompatible.',
52
- ARCANE_EVENT_AUTHORITY_PROTOCOL_MISMATCH:
53
- 'globalThis.arcaneEvents uses an incompatible authority protocol.',
54
- ARCANE_EVENT_AUTHORITY_API_MISMATCH:
55
- 'globalThis.arcaneEvents does not expose the required authority API.',
56
45
  ARCANE_EVENT_AUTHORITY_INSTALL_FAILED:
57
46
  'The Arcane event authority could not be installed on globalThis.',
58
47
  ARCANE_EVENT_SOURCE_INVALID:
@@ -63,8 +52,6 @@ const ARCANE_EVENT_ERRORS={
63
52
  'The Arcane event source is disposed.',
64
53
  ARCANE_EVENT_SOURCE_EVENT_TYPE_UNDECLARED:
65
54
  'The Arcane event source cannot publish an undeclared event type.',
66
- ARCANE_EVENT_COMPATIBILITY_DETAIL_INVALID:
67
- 'Arcane event compatibility detail must be safely shallow-copyable.',
68
55
  ARCANE_EVENT_OCCURRENCE_INVALID:
69
56
  'The Arcane event occurrence value or creation options are invalid.',
70
57
  ARCANE_EVENT_OCCURRENCE_SEQUENCE_EXHAUSTED:
@@ -74,7 +61,7 @@ const ARCANE_EVENT_ERRORS={
74
61
  ARCANE_EVENT_LISTENER_CALLBACK_FAILED:
75
62
  'An Arcane event listener threw during observational delivery.',
76
63
  ARCANE_EVENT_DOM_DETAIL_COLLISION:
77
- 'Arcane DOM projection metadata conflicts with compatibility detail.',
64
+ 'Arcane DOM projection metadata conflicts with source detail.',
78
65
  ARCANE_EVENT_DOM_TARGET_INVALID:
79
66
  'Arcane DOM projection requires a target with dispatchEvent and CustomEvent support.',
80
67
  ARCANE_EVENT_DOM_OPTIONS_INVALID:
@@ -88,7 +75,7 @@ const ARCANE_EVENT_ERRORS={
88
75
  ARCANE_EVENT_SUBSCRIPTION_SIGNAL_INVALID:
89
76
  'Arcane event subscription signal must be an AbortSignal.',
90
77
  ARCANE_EVENT_DISPATCH_EVENT_INVALID:
91
- 'arcaneEvents.dispatchEvent requires an Event-like object with a valid type and data detail.'
78
+ 'dispatchEvent requires an Event-like object with a valid type and data detail.'
92
79
  };
93
80
  export const ARCANE_EVENT_ERROR_CODES=Object.fromEntries(
94
81
  Object.keys(ARCANE_EVENT_ERRORS).map(code=>[code,code])
@@ -1345,7 +1332,7 @@ function createArcaneEventAuthority(){
1345
1332
  const compatibilityByOccurrence=new WeakMap();
1346
1333
  const sourceRecordByOccurrence=new WeakMap();
1347
1334
  const authorityTargetListeners=[];
1348
- const legacyListeners=[];
1335
+ const directListeners=[];
1349
1336
  let occurrenceSequence=0;
1350
1337
  let sourceSequence=0;
1351
1338
  let reportingListenerError=false;
@@ -1664,9 +1651,9 @@ function createArcaneEventAuthority(){
1664
1651
  record.unsubscribe();
1665
1652
  }
1666
1653
 
1667
- function dispatchEventLike(value,sourceRecord=null){
1654
+ function dispatchEventLike(value,sourceRecord){
1668
1655
  const admitted=eventLikeRecord(value);
1669
- if(sourceRecord&&!sourceRecord.eventTypes.has(admitted.type)){
1656
+ if(!sourceRecord.eventTypes.has(admitted.type)){
1670
1657
  throw eventAuthorityError('ARCANE_EVENT_SOURCE_EVENT_TYPE_UNDECLARED');
1671
1658
  }
1672
1659
  const detail=compatibilityDetail(admitted.detail);
@@ -1679,8 +1666,8 @@ function createArcaneEventAuthority(){
1679
1666
  const publication=dispatchOccurrence({
1680
1667
  type:admitted.type,
1681
1668
  sourceRecord,
1682
- source:sourceRecord?.source??ARCANE_EVENT_TARGET_COMPATIBILITY_SOURCE,
1683
- instanceId:sourceRecord?.instanceId??'arcane-source-compatibility',
1669
+ source:sourceRecord.source,
1670
+ instanceId:sourceRecord.instanceId,
1684
1671
  compatibility:detail,
1685
1672
  publicDetail:detail,
1686
1673
  operationId,
@@ -1943,43 +1930,43 @@ function createArcaneEventAuthority(){
1943
1930
  return accepted&&!occurrence.defaultPrevented;
1944
1931
  }
1945
1932
 
1946
- function safeLegacyOn(type,handler,once=false){
1933
+ function safeDirectOn(type,handler,once=false){
1947
1934
  const admittedType=type==='*'?'*':eventName(type);
1948
1935
  const admitted=eventListener(handler);
1949
1936
  if(typeof once!=='boolean'){
1950
1937
  throw eventAuthorityError('ARCANE_EVENT_SUBSCRIPTION_OPTIONS_INVALID',undefined,TypeError);
1951
1938
  }
1952
1939
  const record={type:admittedType,identity:admitted.identity,wrapper:null};
1953
- function safeLegacyListener(value,...rest){
1954
- if(once)removeLegacyRecord(record);
1940
+ function safeDirectListener(value,...rest){
1941
+ if(once)removeDirectRecord(record);
1955
1942
  try{admitted.invoke(value,manager,...rest);}
1956
1943
  catch(error){reportListenerFailure(error,null,null);}
1957
1944
  }
1958
- record.wrapper=safeLegacyListener;
1959
- legacyListeners.push(record);
1960
- manager[EVENT_MANAGER_BUS_ON](admittedType,safeLegacyListener);
1945
+ record.wrapper=safeDirectListener;
1946
+ directListeners.push(record);
1947
+ manager[EVENT_MANAGER_BUS_ON](admittedType,safeDirectListener);
1961
1948
  return manager;
1962
1949
  }
1963
1950
 
1964
- function removeLegacyRecord(record){
1965
- const index=legacyListeners.indexOf(record);
1951
+ function removeDirectRecord(record){
1952
+ const index=directListeners.indexOf(record);
1966
1953
  if(index<0)return false;
1967
- legacyListeners.splice(index,1);
1954
+ directListeners.splice(index,1);
1968
1955
  manager[EVENT_MANAGER_BUS_OFF](record.type,record.wrapper);
1969
1956
  return true;
1970
1957
  }
1971
1958
 
1972
- function safeLegacyOff(type='*',handler='*'){
1959
+ function safeDirectOff(type='*',handler='*'){
1973
1960
  const admittedType=type==='*'?'*':eventName(type);
1974
- const selected=legacyListeners.filter(record=>(admittedType==='*'||record.type===admittedType)
1961
+ const selected=directListeners.filter(record=>(admittedType==='*'||record.type===admittedType)
1975
1962
  &&(handler==='*'||record.identity===handler));
1976
1963
  if(handler!=='*')eventListener(handler);
1977
- for(const record of selected)removeLegacyRecord(record);
1964
+ for(const record of selected)removeDirectRecord(record);
1978
1965
  return manager;
1979
1966
  }
1980
1967
 
1981
- function safeLegacyReset(){
1982
- for(const record of [...legacyListeners])removeLegacyRecord(record);
1968
+ function safeDirectReset(){
1969
+ for(const record of [...directListeners])removeDirectRecord(record);
1983
1970
  return manager;
1984
1971
  }
1985
1972
 
@@ -1987,10 +1974,10 @@ function createArcaneEventAuthority(){
1987
1974
  [ARCANE_EVENT_AUTHORITY_BRAND]:ARCANE_EVENT_AUTHORITY_PROTOCOL,
1988
1975
  protocol:ARCANE_EVENT_AUTHORITY_PROTOCOL,
1989
1976
  descriptor,
1990
- on:safeLegacyOn,
1991
- once:(type,handler)=>safeLegacyOn(type,handler,true),
1992
- off:safeLegacyOff,
1993
- reset:safeLegacyReset,
1977
+ on:safeDirectOn,
1978
+ once:(type,handler)=>safeDirectOn(type,handler,true),
1979
+ off:safeDirectOff,
1980
+ reset:safeDirectReset,
1994
1981
  subscribe,
1995
1982
  createSource,
1996
1983
  projectDOMEvent,
@@ -2007,8 +1994,7 @@ function createArcaneEventAuthority(){
2007
1994
  },
2008
1995
  removeEventListener(type,handler,options){
2009
1996
  removeEventTargetListener(authorityTargetListeners,type,handler,options);
2010
- },
2011
- dispatchEvent:value=>dispatchEventLike(value)
1997
+ }
2012
1998
  });
2013
1999
  return manager;
2014
2000
  }
@@ -82,7 +82,7 @@ function normalizedDocumentPaths(entry,documents){
82
82
  function decodedEscape(source,index){
83
83
  const character=source[index];
84
84
  if(/[1-9]/u.test(character)||(character==='0'&&/[0-9]/u.test(source[index+1]??''))){
85
- fail('Import-map scan found a legacy octal or decimal string escape.');
85
+ fail('Import-map scan found an octal or decimal string escape.');
86
86
  }
87
87
  const simple={b:'\b',f:'\f',n:'\n',r:'\r',t:'\t',v:'\v','0':'\0'};
88
88
  if(Object.hasOwn(simple,character))return {value:simple[character],next:index+1};
package/src/index.mjs CHANGED
@@ -74,9 +74,7 @@ export {
74
74
  export {runDoctor,assessArcaneOllama} from './doctor.mjs';
75
75
  export {
76
76
  ARCANE_NATIVE_PROVIDER_PATHS,
77
- ARCANE_PORTABLE_PROVIDER_PATH,
78
- loadArcaneNativeProvider,
79
- loadArcanePortableProvider
77
+ loadArcaneNativeProvider
80
78
  } from './native-provider-loader.mjs';
81
79
  export {
82
80
  ARCANE_INTEGRATED_PROVIDER_RELATIVE_PATH,
@@ -99,7 +97,6 @@ export {
99
97
  } from './targets/index.mjs';
100
98
  export {
101
99
  assertIntegratedNativeToolchain,
102
- assertIntegratedPortableToolchain,
103
100
  buildApplication,
104
101
  bundleApplication,
105
102
  checkApplication,
@@ -117,7 +114,6 @@ export {
117
114
  planApplication,
118
115
  prepareNativeTarget,
119
116
  resolveNativeBuildOutputRoot,
120
- resolvePortableBuildOutputRoot,
121
117
  repositoryApplication,
122
118
  runApplication,
123
119
  testApplication,
@@ -138,10 +134,7 @@ export {
138
134
  loadSdkBrowserRuntimeRelease,
139
135
  readSdkBrowserRuntimeFile
140
136
  } from './sdk-browser-runtime.mjs';
141
- export {
142
- materializeWorkspaceRuntime,
143
- materializeWorkspaceRuntimeContent
144
- } from './workspace-runtime.mjs';
137
+ export {materializeWorkspaceRuntimeContent} from './workspace-runtime.mjs';
145
138
  export {
146
139
  discoverApps,
147
140
  inspectWorkspaceProfile,