arcane-os 0.5.16 → 0.5.18

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 (190) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +42 -19
  3. package/bin/arcane-test.mjs +16 -13
  4. package/browser-runtime/ai/browser-speech-artifacts.mjs +41 -38
  5. package/browser-runtime/ai/browser-speech-providers.mjs +53 -46
  6. package/browser-runtime/ai/browser-wasm-llm-provider.mjs +127 -124
  7. package/browser-runtime/ai/browser-wasm.mjs +6 -3
  8. package/browser-runtime/ai/browser-wllama-runtime.mjs +26 -23
  9. package/browser-runtime/ai/model-controller.mjs +94 -91
  10. package/browser-runtime/ai/speech-worker-client.mjs +12 -9
  11. package/browser-runtime/ai/speech-worker-runtime.mjs +56 -53
  12. package/browser-runtime/dependencies/strong-type/index.js +207 -82
  13. package/browser-runtime/dependencies/strong-type/package.json +15 -6
  14. package/browser-runtime/dom-event-instrumentation.mjs +24 -20
  15. package/browser-runtime/event-manager.mjs +111 -108
  16. package/browser-runtime/speech-text.mjs +35 -0
  17. package/docs/architecture.md +1 -1
  18. package/docs/reference/README.md +8 -8
  19. package/docs/reference/ai/browser-speech.md +230 -16
  20. package/docs/reference/ai/twin-cloud.md +1 -1
  21. package/docs/reference/availability-and-normalization.md +42 -1
  22. package/docs/reference/cli.md +1 -1
  23. package/docs/reference/core/arcane-ai-contracts.md +1 -1
  24. package/docs/reference/inventory/package-api.json +60 -4
  25. package/docs/reference/inventory/runtime-components.json +2 -2
  26. package/docs/reference/inventory/runtime-modules.json +29 -31
  27. package/docs/reference/protocols.md +17 -13
  28. package/docs/reference/runtime-components.md +6 -5
  29. package/docs/reference/runtime-modules.md +212 -70
  30. package/docs/reference/sdk-api.md +197 -11
  31. package/examples/wasm-ai-demo/index.html +1 -0
  32. package/node_modules/event-pubsub/node_modules/strong-type/README.md +408 -0
  33. package/node_modules/event-pubsub/node_modules/strong-type/assets/strong-type-header.png +0 -0
  34. package/node_modules/event-pubsub/node_modules/strong-type/index.js +1151 -0
  35. package/node_modules/event-pubsub/node_modules/strong-type/licence +21 -0
  36. package/node_modules/event-pubsub/node_modules/strong-type/node.js +125 -0
  37. package/node_modules/event-pubsub/node_modules/strong-type/package.json +61 -0
  38. package/node_modules/strong-type/README.md +42 -24
  39. package/node_modules/strong-type/benchmark/core.js +324 -0
  40. package/node_modules/strong-type/index.js +207 -82
  41. package/node_modules/strong-type/package.json +14 -6
  42. package/package.json +4 -3
  43. package/runtime/arcane/components/app-bar.html +5 -2
  44. package/runtime/arcane/components/assistant-panel.html +5 -2
  45. package/runtime/arcane/components/chart.html +15 -12
  46. package/runtime/arcane/components/chat.html +118 -141
  47. package/runtime/arcane/components/dashboard-config.html +6 -3
  48. package/runtime/arcane/components/data-view.html +4 -1
  49. package/runtime/arcane/components/directory-picker.html +5 -2
  50. package/runtime/arcane/components/document-inspector.html +6 -3
  51. package/runtime/arcane/components/file-drop.html +5 -2
  52. package/runtime/arcane/components/file-inspector.html +9 -6
  53. package/runtime/arcane/components/file-manager.html +16 -13
  54. package/runtime/arcane/components/local-ai-status.html +5 -2
  55. package/runtime/arcane/components/markdown-document.html +14 -11
  56. package/runtime/arcane/components/markdown-editor.html +4 -1
  57. package/runtime/arcane/components/modal.html +4 -1
  58. package/runtime/arcane/components/output-panel.html +6 -3
  59. package/runtime/arcane/components/preferences-form.html +4 -1
  60. package/runtime/arcane/components/record-timeline.html +8 -5
  61. package/runtime/arcane/components/relationship-board.html +9 -6
  62. package/runtime/arcane/components/source-code-viewer.html +12 -9
  63. package/runtime/arcane/components/source-explanation.html +8 -5
  64. package/runtime/arcane/components/speech.html +24 -21
  65. package/runtime/arcane/components/summary-strip.html +4 -1
  66. package/runtime/arcane/components/task-progress.html +6 -3
  67. package/runtime/arcane/components/terminal-workspace.html +4 -1
  68. package/runtime/arcane/components/voice-transcription.html +11 -8
  69. package/runtime/arcane/components/web-navigator.html +5 -2
  70. package/runtime/arcane/entities/ApiModelRecord.js +5 -2
  71. package/runtime/arcane/entities/Calculation.js +5 -2
  72. package/runtime/arcane/entities/Chat.js +33 -33
  73. package/runtime/arcane/entities/CommunicationMessage.js +4 -1
  74. package/runtime/arcane/entities/CommunicationThread.js +4 -1
  75. package/runtime/arcane/entities/File.js +1 -1
  76. package/runtime/arcane/entities/Image.js +8 -5
  77. package/runtime/arcane/entities/IntentEnvelope.js +20 -17
  78. package/runtime/arcane/entities/Preference.js +9 -6
  79. package/runtime/arcane/entities/Theme.js +5 -2
  80. package/runtime/arcane/entities/User.js +11 -11
  81. package/runtime/arcane/entities/Weather.js +5 -2
  82. package/runtime/arcane/modules/AI.js +503 -187
  83. package/runtime/arcane/modules/AIPreferenceRuntime.js +5 -2
  84. package/runtime/arcane/modules/AIPreferenceTuple.js +9 -6
  85. package/runtime/arcane/modules/AIProviderRuntime.js +117 -92
  86. package/runtime/arcane/modules/AIResponseURLPolicy.js +148 -62
  87. package/runtime/arcane/modules/AIRuntimeState.js +29 -26
  88. package/runtime/arcane/modules/AnsiText.js +4 -1
  89. package/runtime/arcane/modules/ApiModelDatabase.js +22 -19
  90. package/runtime/arcane/modules/AppDataScope.js +8 -5
  91. package/runtime/arcane/modules/ArcaneCommunicationBridge.js +4 -1
  92. package/runtime/arcane/modules/ArcaneNavigationPolicy.js +8 -5
  93. package/runtime/arcane/modules/ArcaneNetworkPolicy.js +18 -15
  94. package/runtime/arcane/modules/AsyncBoundary.js +13 -10
  95. package/runtime/arcane/modules/BrowserTestSuite.js +19 -16
  96. package/runtime/arcane/modules/CalculatorEngine.js +5 -2
  97. package/runtime/arcane/modules/ChatRecords.js +18 -15
  98. package/runtime/arcane/modules/CommunicationAppController.js +9 -6
  99. package/runtime/arcane/modules/CommunicationHub.js +9 -6
  100. package/runtime/arcane/modules/CommunicationPreferences.js +4 -1
  101. package/runtime/arcane/modules/CommunicationProviderRegistry.js +4 -1
  102. package/runtime/arcane/modules/ComponentContracts.js +56 -53
  103. package/runtime/arcane/modules/ConfiguredAIChatSession.js +30 -27
  104. package/runtime/arcane/modules/ConversationActionItems.js +15 -12
  105. package/runtime/arcane/modules/ConversationClosingReport.js +11 -8
  106. package/runtime/arcane/modules/ConversationTimebox.js +28 -25
  107. package/runtime/arcane/modules/CoreLocalModelCatalog.js +17 -14
  108. package/runtime/arcane/modules/DBLS.js +7 -4
  109. package/runtime/arcane/modules/DBOPFS.js +7 -7
  110. package/runtime/arcane/modules/DBOPFSDocumentLibrary.js +34 -31
  111. package/runtime/arcane/modules/DevelopmentWorkspace.js +4 -1
  112. package/runtime/arcane/modules/DirectoryPicker.js +8 -5
  113. package/runtime/arcane/modules/DocumentLexicalSearch.js +11 -8
  114. package/runtime/arcane/modules/DocumentNavigation.js +7 -4
  115. package/runtime/arcane/modules/Errors.js +28 -25
  116. package/runtime/arcane/modules/HTMLImport.js +7 -4
  117. package/runtime/arcane/modules/IsolatedModelQuestionRunner.js +15 -12
  118. package/runtime/arcane/modules/LocalAIReadiness.js +21 -18
  119. package/runtime/arcane/modules/LocalAIReadinessController.js +6 -3
  120. package/runtime/arcane/modules/MD.js +1 -1
  121. package/runtime/arcane/modules/Mail.js +46 -43
  122. package/runtime/arcane/modules/MailOutbox.mjs +48 -45
  123. package/runtime/arcane/modules/MailTransport.mjs +29 -26
  124. package/runtime/arcane/modules/MarkdownSpeech.js +1 -50
  125. package/runtime/arcane/modules/MemoryRecords.js +7 -4
  126. package/runtime/arcane/modules/MessageAdvisory.js +6 -3
  127. package/runtime/arcane/modules/ModelDefinition.js +7 -4
  128. package/runtime/arcane/modules/Ollama.js +6 -3
  129. package/runtime/arcane/modules/OllamaModelIdentifier.js +4 -1
  130. package/runtime/arcane/modules/OpenMeteoWeatherProvider.js +18 -15
  131. package/runtime/arcane/modules/PersistentAIChatSession.js +33 -30
  132. package/runtime/arcane/modules/PreferenceStore.js +20 -17
  133. package/runtime/arcane/modules/PreparedSpeech.js +485 -0
  134. package/runtime/arcane/modules/Questionnaire.js +6 -3
  135. package/runtime/arcane/modules/RecordLinkIndex.js +4 -1
  136. package/runtime/arcane/modules/RecordPassageIndex.js +9 -6
  137. package/runtime/arcane/modules/RecordReviewStore.js +12 -9
  138. package/runtime/arcane/modules/RiskSignalAnalyzer.js +4 -1
  139. package/runtime/arcane/modules/ScopedOPFSCache.js +6 -3
  140. package/runtime/arcane/modules/ScreenCapture.js +20 -17
  141. package/runtime/arcane/modules/SpeechPlayback.js +61 -28
  142. package/runtime/arcane/modules/StaticDocumentCatalog.js +33 -30
  143. package/runtime/arcane/modules/SystemAppearance.js +5 -2
  144. package/runtime/arcane/modules/SystemToolRegistry.js +6 -3
  145. package/runtime/arcane/modules/TerminalClient.js +14 -11
  146. package/runtime/arcane/modules/TerminalCommandRegistry.js +4 -1
  147. package/runtime/arcane/modules/ThemeBootstrap.js +9 -6
  148. package/runtime/arcane/modules/ThemeManager.js +5 -2
  149. package/runtime/arcane/modules/TimeGuard.js +1 -1
  150. package/runtime/arcane/modules/ToolCallRouter.js +11 -8
  151. package/runtime/arcane/modules/WaitForComponent.js +19 -16
  152. package/runtime/arcane/modules/YouTubeMedia.js +4 -1
  153. package/runtime/strong-type/index.js +1276 -352
  154. package/runtime/strong-type/package.json +69 -45
  155. package/src/app-descriptor.mjs +17 -14
  156. package/src/application-tests.mjs +4 -1
  157. package/src/cli/main.mjs +8 -5
  158. package/src/constants.mjs +4 -1
  159. package/src/dev-server.mjs +8 -5
  160. package/src/doctor.mjs +5 -2
  161. package/src/dom-event-instrumentation.mjs +24 -20
  162. package/src/errors.mjs +7 -3
  163. package/src/event-manager.mjs +111 -108
  164. package/src/event-queue.mjs +8 -5
  165. package/src/events.mjs +12 -9
  166. package/src/import-map.mjs +36 -27
  167. package/src/installed-sdk-runtime.mjs +4 -1
  168. package/src/integrated-provider-loader.mjs +9 -6
  169. package/src/mail-credentials.mjs +16 -13
  170. package/src/mail-server.mjs +53 -50
  171. package/src/mail.mjs +18 -15
  172. package/src/native-plan.mjs +12 -9
  173. package/src/native-provider-loader.mjs +7 -4
  174. package/src/packager/core.mjs +18 -15
  175. package/src/process.mjs +6 -3
  176. package/src/release-bundle.mjs +14 -11
  177. package/src/runtime.mjs +4 -1
  178. package/src/scaffold.mjs +9 -6
  179. package/src/sdk-browser-runtime.mjs +4 -1
  180. package/src/source-server.mjs +17 -14
  181. package/src/targets/index.mjs +5 -2
  182. package/src/templates/workspace-template.mjs +13 -6
  183. package/src/testing-loader.mjs +7 -4
  184. package/src/testing.mjs +10 -7
  185. package/src/toolchain.mjs +13 -10
  186. package/src/update-check.mjs +9 -6
  187. package/src/workspace-operation-lock.mjs +14 -11
  188. package/src/workspace-runtime.mjs +4 -1
  189. package/src/workspace.mjs +17 -14
  190. package/runtime/arcane/modules/AIResponseLength.js +0 -32
@@ -1,6 +1,9 @@
1
+ import Is from 'strong-type';
1
2
  import EventPubSub from 'event-pubsub';
2
3
  import {createDOMInstrumentation} from './dom-event-instrumentation.mjs';
3
4
 
5
+ const is = new Is(false);
6
+
4
7
  export {
5
8
  createDOMInstrumentation,
6
9
  DEFAULT_DOM_EVENT_TYPES,
@@ -145,7 +148,7 @@ function taggedSnapshot(type,entries=[]){
145
148
  function safeDataString(value,key,{fallback=''}={}){
146
149
  try{
147
150
  const current=Reflect.get(value,key);
148
- if(typeof current==='string')return current;
151
+ if(is.string(current))return current;
149
152
  }catch{}
150
153
  return fallback;
151
154
  }
@@ -153,7 +156,7 @@ function safeDataString(value,key,{fallback=''}={}){
153
156
  function regexpFlags(value){
154
157
  let result='';
155
158
  for(const [flag,getter] of REGEXP_FLAG_GETTERS){
156
- if(typeof getter==='function'&&getter.call(value))result+=flag;
159
+ if(is.function(getter)&&getter.call(value))result+=flag;
157
160
  }
158
161
  return result;
159
162
  }
@@ -165,7 +168,7 @@ function safeString(value){
165
168
  function safeErrorText(error){
166
169
  let text='Snapshot capture failed.';
167
170
  try{
168
- if(error!==null&&(typeof error==='object'||typeof error==='function')){
171
+ if(error!==null&&(is.object(error)||is.function(error))){
169
172
  const message=safeDataString(error,'message');
170
173
  if(message)text=message;
171
174
  }else if(error!==undefined){
@@ -177,34 +180,34 @@ function safeErrorText(error){
177
180
  }
178
181
 
179
182
  function sessionIdentifier(){
180
- if(typeof globalThis.crypto?.randomUUID==='function')return globalThis.crypto.randomUUID();
183
+ if(is.function(globalThis.crypto?.randomUUID))return globalThis.crypto.randomUUID();
181
184
  return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
182
185
  }
183
186
 
184
187
  function clockDate(clock){
185
188
  const value=clock();
186
189
  const result=value instanceof Date?new Date(value.getTime()):new Date(value);
187
- if(Number.isNaN(result.getTime()))throw new TypeError('The event clock returned an invalid timestamp.');
190
+ if(is.NaN(result.getTime()))throw new TypeError('The event clock returned an invalid timestamp.');
188
191
  return result;
189
192
  }
190
193
 
191
194
  function monotonicValue(now){
192
195
  const value=Number(now());
193
- if(!Number.isFinite(value)||value<0){
196
+ if(!is.finite(value)||value<0){
194
197
  throw new TypeError('The monotonic event clock returned an invalid value.');
195
198
  }
196
199
  return value;
197
200
  }
198
201
 
199
202
  function defaultMonotonicClock(){
200
- return typeof globalThis.performance?.now==='function'
203
+ return is.function(globalThis.performance?.now)
201
204
  ?globalThis.performance.now()
202
205
  :Date.now();
203
206
  }
204
207
 
205
208
  function sourceStack(){
206
209
  const stack=new Error('Arcane event source').stack;
207
- return typeof stack==='string'?stack:null;
210
+ return is.string(stack)?stack:null;
208
211
  }
209
212
 
210
213
  function snapshot(value,{
@@ -213,20 +216,20 @@ function snapshot(value,{
213
216
  depth=0,
214
217
  seen=new Map()
215
218
  }={}){
216
- if(value===null||value===undefined||typeof value==='boolean')return value;
217
- if(typeof value==='string')return safeString(value);
218
- if(typeof value==='number')return Number.isFinite(value)
219
+ if(value===null||value===undefined||is.boolean(value))return value;
220
+ if(is.string(value))return safeString(value);
221
+ if(is.number(value))return is.finite(value)
219
222
  ?value
220
223
  :taggedSnapshot('number',[['value',String(value)]]);
221
- if(typeof value==='bigint')return taggedSnapshot('bigint',[[
224
+ if(is.bigint(value))return taggedSnapshot('bigint',[[
222
225
  'value',safeString(value.toString())
223
226
  ]]);
224
- if(typeof value==='symbol')return taggedSnapshot('symbol',[[
227
+ if(is.symbol(value))return taggedSnapshot('symbol',[[
225
228
  'value',value.description===undefined
226
229
  ?null
227
230
  :safeString(value.description)
228
231
  ]]);
229
- if(typeof value==='function'){
232
+ if(is.function(value)){
230
233
  const name=safeDataString(value,'name');
231
234
  return taggedSnapshot('function',[[
232
235
  'name',name?safeString(name):null
@@ -275,7 +278,7 @@ function snapshot(value,{
275
278
  }
276
279
  return taggedSnapshot('error',entries);
277
280
  }
278
- if(Array.isArray(value)){
281
+ if(is.array(value)){
279
282
  const result=[];
280
283
  for(let index=0;index<value.length;index+=1){
281
284
  let item;
@@ -306,7 +309,7 @@ function snapshot(value,{
306
309
  }
307
310
  return taggedSnapshot('set',[['values',values]]);
308
311
  }
309
- if(ArrayBuffer.isView(value)){
312
+ if(is.arrayBufferView(value)){
310
313
  const dataView=value instanceof DataView;
311
314
  let values;
312
315
  let type='DataView';
@@ -334,7 +337,7 @@ function snapshot(value,{
334
337
 
335
338
  const result=snapshotObject();
336
339
  const properties=Reflect.ownKeys(value).filter(property=>{
337
- if(typeof property!=='string')return false;
340
+ if(!is.string(property))return false;
338
341
  const descriptor=Object.getOwnPropertyDescriptor(value,property);
339
342
  return descriptor?.enumerable===true;
340
343
  });
@@ -371,13 +374,13 @@ function completeSnapshot(value,options){
371
374
 
372
375
  function completeErrorSnapshot(value,options){
373
376
  const captured=completeSnapshot(value,options);
374
- if(captured&&typeof captured==='object'&&!Array.isArray(captured))return captured;
377
+ if(captured&&is.object(captured)&&!is.array(captured))return captured;
375
378
  return taggedSnapshot('thrown',[['value',captured]]);
376
379
  }
377
380
 
378
381
  function normalizeMetadata(metadata){
379
382
  if(metadata===undefined)return {};
380
- if(metadata===null||typeof metadata!=='object'||Array.isArray(metadata)){
383
+ if(metadata===null||!is.object(metadata)||is.array(metadata)){
381
384
  throw new TypeError('Event instrumentation metadata must be an object.');
382
385
  }
383
386
  return metadata;
@@ -417,11 +420,11 @@ function invalidStack(label){
417
420
 
418
421
  function exactDataObject(value,expectedKeys,label){
419
422
  try{
420
- if(!value||typeof value!=='object'||Array.isArray(value))invalidStack(label);
423
+ if(!value||!is.object(value)||is.array(value))invalidStack(label);
421
424
  const prototype=Object.getPrototypeOf(value);
422
425
  if(prototype!==Object.prototype&&prototype!==null)invalidStack(label);
423
426
  const keys=Reflect.ownKeys(value);
424
- if(keys.length!==expectedKeys.length||keys.some(key=>typeof key!=='string')){
427
+ if(keys.length!==expectedKeys.length||keys.some(key=>!is.string(key))){
425
428
  invalidStack(label);
426
429
  }
427
430
  const expected=new Set(expectedKeys);
@@ -448,11 +451,11 @@ function exactDataObject(value,expectedKeys,label){
448
451
 
449
452
  function denseArrayValues(value,label){
450
453
  try{
451
- if(!Array.isArray(value)||!Number.isSafeInteger(value.length)||value.length<0){
454
+ if(!is.array(value)||!is.safeInteger(value.length)||value.length<0){
452
455
  invalidStack(label);
453
456
  }
454
457
  const keys=Reflect.ownKeys(value);
455
- if(keys.some(key=>typeof key!=='string'))invalidStack(label);
458
+ if(keys.some(key=>!is.string(key)))invalidStack(label);
456
459
  const expected=new Set(['length']);
457
460
  for(let index=0;index<value.length;index+=1)expected.add(String(index));
458
461
  if(keys.length!==expected.size||keys.some(key=>!expected.has(key)))invalidStack(label);
@@ -476,17 +479,17 @@ function cloneImportedValue(value,{
476
479
  depth=0,
477
480
  seen=new WeakSet()
478
481
  }){
479
- if(value===null||typeof value==='boolean')return value;
480
- if(typeof value==='number'){
481
- if(!Number.isFinite(value))invalidStack(`Event stack value at ${path}`);
482
+ if(value===null||is.boolean(value))return value;
483
+ if(is.number(value)){
484
+ if(!is.finite(value))invalidStack(`Event stack value at ${path}`);
482
485
  return value;
483
486
  }
484
- if(typeof value==='string')return value;
485
- if(!value||typeof value!=='object')invalidStack(`Event stack value at ${path}`);
487
+ if(is.string(value))return value;
488
+ if(!value||!is.object(value))invalidStack(`Event stack value at ${path}`);
486
489
  if(seen.has(value))invalidStack(`Event stack value at ${path}`);
487
490
  seen.add(value);
488
491
 
489
- if(Array.isArray(value)){
492
+ if(is.array(value)){
490
493
  const items=denseArrayValues(value,`Event stack array at ${path}`);
491
494
  return items.map((item,index)=>cloneImportedValue(item,{
492
495
  path:`${path}[${String(index)}]`,
@@ -504,7 +507,7 @@ function cloneImportedValue(value,{
504
507
  throw new TypeError(`Event stack value at ${path} is invalid.`,{cause:error});
505
508
  }
506
509
  if((prototype!==Object.prototype&&prototype!==null)
507
- ||keys.some(key=>typeof key!=='string')){
510
+ ||keys.some(key=>!is.string(key))){
508
511
  invalidStack(`Event stack value at ${path}`);
509
512
  }
510
513
  const result=dataObject();
@@ -531,9 +534,9 @@ function cloneImportedValue(value,{
531
534
  }
532
535
 
533
536
  function canonicalTimestamp(value,label){
534
- if(typeof value!=='string')invalidStack(label);
537
+ if(!is.string(value))invalidStack(label);
535
538
  const milliseconds=Date.parse(value);
536
- if(!Number.isFinite(milliseconds)||new Date(milliseconds).toISOString()!==value){
539
+ if(!is.finite(milliseconds)||new Date(milliseconds).toISOString()!==value){
537
540
  invalidStack(label);
538
541
  }
539
542
  return milliseconds;
@@ -541,7 +544,7 @@ function canonicalTimestamp(value,label){
541
544
 
542
545
  function recordString(value,label,{nullable=false,empty=true}={}){
543
546
  if(nullable&&value===null)return null;
544
- if(typeof value!=='string'||(!empty&&!value)){
547
+ if(!is.string(value)||(!empty&&!value)){
545
548
  invalidStack(label);
546
549
  }
547
550
  return value;
@@ -555,12 +558,12 @@ function validateRecord(record,index,{
555
558
  if(fields.protocol!==ARCANE_EVENT_STACK_PROTOCOL||fields.sessionId!==sessionId){
556
559
  invalidStack(label);
557
560
  }
558
- if(!Number.isSafeInteger(fields.sequence)||fields.sequence<1
561
+ if(!is.safeInteger(fields.sequence)||fields.sequence<1
559
562
  ||fields.id!==`${sessionId}:${String(fields.sequence)}`){
560
563
  invalidStack(label);
561
564
  }
562
565
  const timestampMs=canonicalTimestamp(fields.timestamp,`${label} timestamp`);
563
- if(typeof fields.monotonicMs!=='number'||!Number.isFinite(fields.monotonicMs)
566
+ if(!is.number(fields.monotonicMs)||!is.finite(fields.monotonicMs)
564
567
  ||fields.monotonicMs<0){
565
568
  invalidStack(`${label} monotonic timing`);
566
569
  }
@@ -576,11 +579,11 @@ function validateRecord(record,index,{
576
579
  nullable:true,empty:false
577
580
  });
578
581
  if(fields.parentSequence!==null
579
- &&(!Number.isSafeInteger(fields.parentSequence)||fields.parentSequence<1
582
+ &&(!is.safeInteger(fields.parentSequence)||fields.parentSequence<1
580
583
  ||fields.parentSequence>=fields.sequence)){
581
584
  invalidStack(`${label} parent`);
582
585
  }
583
- if(!Number.isSafeInteger(fields.depth)||fields.depth<0
586
+ if(!is.safeInteger(fields.depth)||fields.depth<0
584
587
  ||(fields.parentSequence===null)!==(fields.depth===0)){
585
588
  invalidStack(`${label} depth`);
586
589
  }
@@ -598,7 +601,7 @@ function validateRecord(record,index,{
598
601
  depth:0,
599
602
  seen:new WeakSet()
600
603
  });
601
- if(!metadata||typeof metadata!=='object'||Array.isArray(metadata)){
604
+ if(!metadata||!is.object(metadata)||is.array(metadata)){
602
605
  invalidStack(`${label} metadata`);
603
606
  }
604
607
 
@@ -612,7 +615,7 @@ function validateRecord(record,index,{
612
615
  }else{
613
616
  const completedAtMs=canonicalTimestamp(fields.completedAt,`${label} completion timestamp`);
614
617
  if(completedAtMs<timestampMs
615
- ||typeof fields.durationMs!=='number'||!Number.isFinite(fields.durationMs)
618
+ ||!is.number(fields.durationMs)||!is.finite(fields.durationMs)
616
619
  ||fields.durationMs<0){
617
620
  invalidStack(`${label} completion timing`);
618
621
  }
@@ -626,7 +629,7 @@ function validateRecord(record,index,{
626
629
  depth:0,
627
630
  seen:new WeakSet()
628
631
  });
629
- if(!error||typeof error!=='object'||Array.isArray(error)){
632
+ if(!error||!is.object(error)||is.array(error)){
630
633
  invalidStack(`${label} error`);
631
634
  }
632
635
  }
@@ -658,14 +661,14 @@ function validateRecord(record,index,{
658
661
 
659
662
  export function parseEventStack(source){
660
663
  let document=source;
661
- if(typeof source==='string'){
664
+ if(is.string(source)){
662
665
  try{document=JSON.parse(source);}catch(error){
663
666
  throw new TypeError('The event stack is not valid JSON.',{cause:error});
664
667
  }
665
668
  }
666
669
  const fields=exactDataObject(document,DOCUMENT_KEYS,'The event stack document');
667
670
  if(fields.protocol!==ARCANE_EVENT_STACK_PROTOCOL
668
- ||typeof fields.sessionId!=='string'||!fields.sessionId){
671
+ ||!is.string(fields.sessionId)||!fields.sessionId){
669
672
  invalidStack('The event stack document');
670
673
  }
671
674
  canonicalTimestamp(fields.createdAt,'The event stack creation timestamp');
@@ -715,13 +718,13 @@ export class EventManager{
715
718
  now=defaultMonotonicClock,
716
719
  sessionId=sessionIdentifier()
717
720
  }={}){
718
- if(typeof timeTravel!=='boolean'){
721
+ if(!is.boolean(timeTravel)){
719
722
  throw new TypeError('EventManager flags must be boolean values.');
720
723
  }
721
- if(typeof clock!=='function'||typeof now!=='function'){
724
+ if(!is.function(clock)||!is.function(now)){
722
725
  throw new TypeError('EventManager clocks must be functions.');
723
726
  }
724
- if(typeof sessionId!=='string'||!sessionId){
727
+ if(!is.string(sessionId)||!sessionId){
725
728
  throw new TypeError('EventManager sessionId must be a non-empty string.');
726
729
  }
727
730
  this.#clock=clock;
@@ -783,14 +786,14 @@ export class EventManager{
783
786
  }
784
787
 
785
788
  forward(event,metadata={}){
786
- if(!event||typeof event!=='object'||Array.isArray(event)||typeof event.type!=='string'){
789
+ if(!event||!is.object(event)||is.array(event)||!is.string(event.type)){
787
790
  throw new TypeError('Forwarded events must be objects with a string type.');
788
791
  }
789
792
  return this.instrument(event.type,event,metadata);
790
793
  }
791
794
 
792
795
  #dispatch(type,payload,metadata){
793
- if(typeof type!=='string'){
796
+ if(!is.string(type)){
794
797
  this.#bus.emit(type,...payload);
795
798
  return this;
796
799
  }
@@ -803,8 +806,8 @@ export class EventManager{
803
806
  startedMonotonic=monotonicValue(this.#now);
804
807
  const payloadSnapshot=completeSnapshot(payload);
805
808
  const metadataSnapshot=completeSnapshot(metadata);
806
- const safeMetadata=metadataSnapshot&&typeof metadataSnapshot==='object'
807
- &&!Array.isArray(metadataSnapshot)
809
+ const safeMetadata=metadataSnapshot&&is.object(metadataSnapshot)
810
+ &&!is.array(metadataSnapshot)
808
811
  ?metadataSnapshot
809
812
  :snapshotObject();
810
813
  const sequence=this.#sequence+1;
@@ -823,23 +826,23 @@ export class EventManager{
823
826
  timestamp,
824
827
  monotonicMs:startedMonotonic,
825
828
  type:safeString(type),
826
- source:typeof safeMetadata.source==='string'&&safeMetadata.source
829
+ source:is.string(safeMetadata.source)&&safeMetadata.source
827
830
  ?safeString(safeMetadata.source)
828
831
  :'application',
829
- category:typeof safeMetadata.category==='string'&&safeMetadata.category
832
+ category:is.string(safeMetadata.category)&&safeMetadata.category
830
833
  ?safeString(safeMetadata.category)
831
834
  :null,
832
- correlationId:typeof safeMetadata.correlationId==='string'
835
+ correlationId:is.string(safeMetadata.correlationId)
833
836
  &&safeMetadata.correlationId
834
837
  ?safeString(safeMetadata.correlationId):null,
835
- causationId:typeof safeMetadata.causationId==='string'
838
+ causationId:is.string(safeMetadata.causationId)
836
839
  &&safeMetadata.causationId
837
840
  ?safeString(safeMetadata.causationId)
838
841
  :(parentSequence===null?null:`${this.#sessionId}:${parentSequence}`),
839
842
  parentSequence,
840
843
  depth:this.#activeDispatch.length,
841
844
  stack,
842
- payload:Array.isArray(payloadSnapshot)
845
+ payload:is.array(payloadSnapshot)
843
846
  ?payloadSnapshot
844
847
  :[payloadSnapshot],
845
848
  metadata:safeMetadata,
@@ -944,7 +947,7 @@ export class EventManager{
944
947
  if(replacement.active||replacement.cleanupPending){
945
948
  this.#domInstrumentation=replacement;
946
949
  try{
947
- if(error&&(typeof error==='object'||typeof error==='function')){
950
+ if(error&&(is.object(error)||is.function(error))){
948
951
  Object.defineProperty(error,'domInstrumentation',{
949
952
  value:replacement,
950
953
  enumerable:false,
@@ -972,7 +975,7 @@ export class EventManager{
972
975
  }
973
976
 
974
977
  clearHistory({newSession=true}={}){
975
- if(typeof newSession!=='boolean')throw new TypeError('newSession must be boolean.');
978
+ if(!is.boolean(newSession))throw new TypeError('newSession must be boolean.');
976
979
  if(this.#activeDispatch.length||this.#replaying){
977
980
  throw new Error('Event history cannot be cleared during dispatch or playback.');
978
981
  }
@@ -985,9 +988,9 @@ export class EventManager{
985
988
  }
986
989
 
987
990
  getEventStack({fromSequence=1,toSequence=Number.MAX_SAFE_INTEGER,type=null}={}){
988
- if(!Number.isSafeInteger(fromSequence)||fromSequence<1
989
- ||!Number.isSafeInteger(toSequence)||toSequence<fromSequence
990
- ||(type!==null&&typeof type!=='string')){
991
+ if(!is.safeInteger(fromSequence)||fromSequence<1
992
+ ||!is.safeInteger(toSequence)||toSequence<fromSequence
993
+ ||(type!==null&&!is.string(type))){
991
994
  throw new TypeError('The event stack range is invalid.');
992
995
  }
993
996
  return this.#history.filter(record=>
@@ -997,7 +1000,7 @@ export class EventManager{
997
1000
  }
998
1001
 
999
1002
  exportStack({space=2}={}){
1000
- if(!Number.isSafeInteger(space)||space<0||space>10){
1003
+ if(!is.safeInteger(space)||space<0||space>10){
1001
1004
  throw new RangeError('Event stack JSON indentation must be from 0 through 10.');
1002
1005
  }
1003
1006
  return JSON.stringify({
@@ -1009,7 +1012,7 @@ export class EventManager{
1009
1012
  }
1010
1013
 
1011
1014
  seek(sequence){
1012
- if(!Number.isSafeInteger(sequence)||sequence<0||sequence>this.#sequence){
1015
+ if(!is.safeInteger(sequence)||sequence<0||sequence>this.#sequence){
1013
1016
  throw new RangeError('The time-travel sequence is outside this event stack.');
1014
1017
  }
1015
1018
  this.#cursor=sequence;
@@ -1027,17 +1030,17 @@ export class EventManager{
1027
1030
  signal,
1028
1031
  onRecord
1029
1032
  }={}){
1030
- if(!Number.isSafeInteger(fromSequence)||fromSequence<1
1031
- ||!Number.isSafeInteger(toSequence)||toSequence<fromSequence){
1033
+ if(!is.safeInteger(fromSequence)||fromSequence<1
1034
+ ||!is.safeInteger(toSequence)||toSequence<fromSequence){
1032
1035
  throw new TypeError('The playback range is invalid.');
1033
1036
  }
1034
- if(typeof speed!=='number'||!Number.isFinite(speed)||speed<0){
1037
+ if(!is.number(speed)||!is.finite(speed)||speed<0){
1035
1038
  throw new RangeError('Playback speed must be zero or a positive finite number.');
1036
1039
  }
1037
1040
  if(!['review','events','none'].includes(mode)){
1038
1041
  throw new TypeError('Playback mode must be review, events, or none.');
1039
1042
  }
1040
- if(onRecord!==undefined&&typeof onRecord!=='function'){
1043
+ if(onRecord!==undefined&&!is.function(onRecord)){
1041
1044
  throw new TypeError('onRecord must be a function.');
1042
1045
  }
1043
1046
  if(this.#replaying)throw new Error('Event playback is already active.');
@@ -1065,13 +1068,13 @@ export class EventManager{
1065
1068
  if(signal?.aborted)throw abortError(signal.reason);
1066
1069
  if(speed>0&&(previousTimestamp!==null||previousMonotonic!==null)){
1067
1070
  const monotonic=Number(record.monotonicMs);
1068
- const difference=Number.isFinite(monotonic)&&previousMonotonic!==null
1071
+ const difference=is.finite(monotonic)&&previousMonotonic!==null
1069
1072
  ?Math.max(0,monotonic-previousMonotonic)
1070
1073
  :Math.max(0,Date.parse(record.timestamp)-previousTimestamp);
1071
1074
  await wait(difference/speed,signal);
1072
1075
  }
1073
1076
  previousTimestamp=Date.parse(record.timestamp);
1074
- previousMonotonic=Number.isFinite(Number(record.monotonicMs))
1077
+ previousMonotonic=is.finite(Number(record.monotonicMs))
1075
1078
  ?Number(record.monotonicMs)
1076
1079
  :null;
1077
1080
  if(mode==='review')this.#bus.emit(PLAYBACK_RECORD_EVENT,record);
@@ -1118,7 +1121,7 @@ function eventAuthorityError(code,cause,ErrorType=Error){
1118
1121
  }
1119
1122
 
1120
1123
  function eventName(value,code='ARCANE_EVENT_SUBSCRIPTION_TYPE_INVALID'){
1121
- if(typeof value!=='string'
1124
+ if(!is.string(value)
1122
1125
  ||value.trim()!==value
1123
1126
  ||value.length<1
1124
1127
  ||!ARCANE_EVENT_NAME_PATTERN.test(value)){
@@ -1129,7 +1132,7 @@ function eventName(value,code='ARCANE_EVENT_SUBSCRIPTION_TYPE_INVALID'){
1129
1132
 
1130
1133
  function eventDataOptions(value,allowed,code){
1131
1134
  if(value===undefined)return Object.create(null);
1132
- if(!value||typeof value!=='object'||Array.isArray(value)){
1135
+ if(!value||!is.object(value)||is.array(value)){
1133
1136
  throw eventAuthorityError(code,undefined,TypeError);
1134
1137
  }
1135
1138
  const prototype=Object.getPrototypeOf(value);
@@ -1138,7 +1141,7 @@ function eventDataOptions(value,allowed,code){
1138
1141
  }
1139
1142
  const result=Object.create(null);
1140
1143
  for(const key of Reflect.ownKeys(value)){
1141
- if(typeof key!=='string'||!allowed.has(key)){
1144
+ if(!is.string(key)||!allowed.has(key)){
1142
1145
  throw eventAuthorityError(code,undefined,TypeError);
1143
1146
  }
1144
1147
  const descriptor=Object.getOwnPropertyDescriptor(value,key);
@@ -1153,10 +1156,10 @@ function eventDataOptions(value,allowed,code){
1153
1156
  function eventSignal(value){
1154
1157
  if(value===undefined||value===null)return null;
1155
1158
  if(!value
1156
- ||typeof value!=='object'
1157
- ||typeof value.aborted!=='boolean'
1158
- ||typeof value.addEventListener!=='function'
1159
- ||typeof value.removeEventListener!=='function'){
1159
+ ||!is.object(value)
1160
+ ||!is.boolean(value.aborted)
1161
+ ||!is.function(value.addEventListener)
1162
+ ||!is.function(value.removeEventListener)){
1160
1163
  throw eventAuthorityError(
1161
1164
  'ARCANE_EVENT_SUBSCRIPTION_SIGNAL_INVALID',
1162
1165
  undefined,
@@ -1167,13 +1170,13 @@ function eventSignal(value){
1167
1170
  }
1168
1171
 
1169
1172
  function eventListener(value){
1170
- if(typeof value==='function'){
1173
+ if(is.function(value)){
1171
1174
  return {
1172
1175
  identity:value,
1173
1176
  invoke(event,thisArg,...rest){return value.call(thisArg,event,...rest);}
1174
1177
  };
1175
1178
  }
1176
- if(value&&typeof value==='object'&&typeof value.handleEvent==='function'){
1179
+ if(value&&is.object(value)&&is.function(value.handleEvent)){
1177
1180
  return {
1178
1181
  identity:value,
1179
1182
  invoke(event){return value.handleEvent(event);}
@@ -1187,13 +1190,13 @@ function eventListener(value){
1187
1190
  }
1188
1191
 
1189
1192
  function eventTargetListener(value){
1190
- if(typeof value==='function'){
1193
+ if(is.function(value)){
1191
1194
  return {
1192
1195
  identity:value,
1193
1196
  invoke(event,thisArg,...rest){return value.call(thisArg,event,...rest);}
1194
1197
  };
1195
1198
  }
1196
- if(value&&typeof value==='object'&&typeof value.handleEvent==='function'){
1199
+ if(value&&is.object(value)&&is.function(value.handleEvent)){
1197
1200
  return {
1198
1201
  identity:value,
1199
1202
  invoke(event){return value.handleEvent(event);}
@@ -1203,8 +1206,8 @@ function eventTargetListener(value){
1203
1206
  }
1204
1207
 
1205
1208
  function compatibilityDetail(value){
1206
- if(value===null||(typeof value!=='object'&&typeof value!=='function'))return value;
1207
- if(Array.isArray(value))return value.slice();
1209
+ if(value===null||(!is.object(value)&&!is.function(value)))return value;
1210
+ if(is.array(value))return value.slice();
1208
1211
  const prototype=Object.getPrototypeOf(value);
1209
1212
  if(prototype!==Object.prototype&&prototype!==null)return value;
1210
1213
  const copy=prototype===null?Object.create(null):{};
@@ -1226,7 +1229,7 @@ function compatibilityDetail(value){
1226
1229
 
1227
1230
  function eventTargetOptions(value){
1228
1231
  if(value===undefined)return {capture:false,once:false,signal:null};
1229
- if(typeof value==='boolean'){
1232
+ if(is.boolean(value)){
1230
1233
  return {capture:value,once:false,signal:null};
1231
1234
  }
1232
1235
  const options=eventDataOptions(
@@ -1235,7 +1238,7 @@ function eventTargetOptions(value){
1235
1238
  'ARCANE_EVENT_SUBSCRIPTION_OPTIONS_INVALID'
1236
1239
  );
1237
1240
  for(const key of ['capture','once','passive']){
1238
- if(options[key]!==undefined&&typeof options[key]!=='boolean'){
1241
+ if(options[key]!==undefined&&!is.boolean(options[key])){
1239
1242
  throw eventAuthorityError(
1240
1243
  'ARCANE_EVENT_SUBSCRIPTION_OPTIONS_INVALID',
1241
1244
  undefined,
@@ -1256,7 +1259,7 @@ function subscriptionOptions(value){
1256
1259
  new Set(['once','signal']),
1257
1260
  'ARCANE_EVENT_SUBSCRIPTION_OPTIONS_INVALID'
1258
1261
  );
1259
- if(options.once!==undefined&&typeof options.once!=='boolean'){
1262
+ if(options.once!==undefined&&!is.boolean(options.once)){
1260
1263
  throw eventAuthorityError(
1261
1264
  'ARCANE_EVENT_SUBSCRIPTION_OPTIONS_INVALID',
1262
1265
  undefined,
@@ -1281,16 +1284,16 @@ function defineDisposable(unsubscribe){
1281
1284
 
1282
1285
  function eventLikeRecord(value){
1283
1286
  try{
1284
- if(!value||typeof value!=='object'||Array.isArray(value))throw new TypeError();
1287
+ if(!value||!is.object(value)||is.array(value))throw new TypeError();
1285
1288
  const EventConstructor=globalThis.Event;
1286
- if(typeof EventConstructor==='function'&&value instanceof EventConstructor){
1289
+ if(is.function(EventConstructor)&&value instanceof EventConstructor){
1287
1290
  if(!('detail' in value))throw new TypeError();
1288
1291
  return {
1289
1292
  type:eventName(value.type,'ARCANE_EVENT_DISPATCH_EVENT_INVALID'),
1290
1293
  detail:value.detail,
1291
1294
  cancelable:value.cancelable===true,
1292
1295
  defaultPrevented:value.defaultPrevented===true,
1293
- preventDefault:typeof value.preventDefault==='function'
1296
+ preventDefault:is.function(value.preventDefault)
1294
1297
  ?()=>value.preventDefault()
1295
1298
  :null
1296
1299
  };
@@ -1310,7 +1313,7 @@ function eventLikeRecord(value){
1310
1313
  detail:detailDescriptor?.value,
1311
1314
  cancelable:cancelableDescriptor?.value===true,
1312
1315
  defaultPrevented:preventedDescriptor?.value===true,
1313
- preventDefault:typeof value.preventDefault==='function'
1316
+ preventDefault:is.function(value.preventDefault)
1314
1317
  ?()=>value.preventDefault()
1315
1318
  :null
1316
1319
  };
@@ -1363,7 +1366,7 @@ function createArcaneEventAuthority(){
1363
1366
 
1364
1367
  function directListenerFailure(error){
1365
1368
  try{
1366
- if(typeof globalThis.reportError==='function'){
1369
+ if(is.function(globalThis.reportError)){
1367
1370
  globalThis.reportError(error);
1368
1371
  return;
1369
1372
  }
@@ -1378,10 +1381,10 @@ function createArcaneEventAuthority(){
1378
1381
 
1379
1382
  function completeEventDetail(compatibility,publicDetail){
1380
1383
  if(publicDetail===undefined)return compatibility??{};
1381
- const compatibilityRecord=compatibility&&typeof compatibility==='object'
1382
- &&!Array.isArray(compatibility);
1383
- const publicRecord=publicDetail&&typeof publicDetail==='object'
1384
- &&!Array.isArray(publicDetail);
1384
+ const compatibilityRecord=compatibility&&is.object(compatibility)
1385
+ &&!is.array(compatibility);
1386
+ const publicRecord=publicDetail&&is.object(publicDetail)
1387
+ &&!is.array(publicDetail);
1385
1388
  if(compatibilityRecord&&publicRecord)return {...compatibility,...publicDetail};
1386
1389
  return {compatibility,publicDetail};
1387
1390
  }
@@ -1657,8 +1660,8 @@ function createArcaneEventAuthority(){
1657
1660
  throw eventAuthorityError('ARCANE_EVENT_SOURCE_EVENT_TYPE_UNDECLARED');
1658
1661
  }
1659
1662
  const detail=compatibilityDetail(admitted.detail);
1660
- const operationId=detail&&typeof detail==='object'
1661
- &&typeof detail.operationId==='string'
1663
+ const operationId=detail&&is.object(detail)
1664
+ &&is.string(detail.operationId)
1662
1665
  &&detail.operationId.trim()===detail.operationId
1663
1666
  &&detail.operationId
1664
1667
  ?detail.operationId
@@ -1679,7 +1682,7 @@ function createArcaneEventAuthority(){
1679
1682
  }
1680
1683
 
1681
1684
  function createSource(owner,options){
1682
- if(!owner||(typeof owner!=='object'&&typeof owner!=='function')){
1685
+ if(!owner||(!is.object(owner)&&!is.function(owner))){
1683
1686
  throw eventAuthorityError('ARCANE_EVENT_SOURCE_INVALID',undefined,TypeError);
1684
1687
  }
1685
1688
  const admitted=eventDataOptions(
@@ -1688,7 +1691,7 @@ function createArcaneEventAuthority(){
1688
1691
  'ARCANE_EVENT_SOURCE_INVALID'
1689
1692
  );
1690
1693
  const source=eventName(admitted.source,'ARCANE_EVENT_SOURCE_INVALID');
1691
- if(!Array.isArray(admitted.eventTypes)
1694
+ if(!is.array(admitted.eventTypes)
1692
1695
  ||admitted.eventTypes.length<1){
1693
1696
  throw eventAuthorityError('ARCANE_EVENT_SOURCE_INVALID',undefined,TypeError);
1694
1697
  }
@@ -1703,7 +1706,7 @@ function createArcaneEventAuthority(){
1703
1706
  eventTypes.push(normalized);
1704
1707
  }
1705
1708
  if(admitted.onListenerError!==undefined
1706
- &&typeof admitted.onListenerError!=='function'){
1709
+ &&!is.function(admitted.onListenerError)){
1707
1710
  throw eventAuthorityError('ARCANE_EVENT_SOURCE_INVALID',undefined,TypeError);
1708
1711
  }
1709
1712
  const existing=sourceByOwner.get(owner);
@@ -1760,12 +1763,12 @@ function createArcaneEventAuthority(){
1760
1763
  'ARCANE_EVENT_OCCURRENCE_INVALID'
1761
1764
  );
1762
1765
  const operationId=normalized.operationId??null;
1763
- if(operationId!==null&&(typeof operationId!=='string'
1766
+ if(operationId!==null&&(!is.string(operationId)
1764
1767
  ||operationId.trim()!==operationId
1765
1768
  ||operationId.length<1)){
1766
1769
  throw eventAuthorityError('ARCANE_EVENT_OCCURRENCE_INVALID',undefined,TypeError);
1767
1770
  }
1768
- if(normalized.cancelable!==undefined&&typeof normalized.cancelable!=='boolean'){
1771
+ if(normalized.cancelable!==undefined&&!is.boolean(normalized.cancelable)){
1769
1772
  throw eventAuthorityError('ARCANE_EVENT_OCCURRENCE_INVALID',undefined,TypeError);
1770
1773
  }
1771
1774
  return dispatchOccurrence({
@@ -1870,21 +1873,21 @@ function createArcaneEventAuthority(){
1870
1873
  ?occurrence.type
1871
1874
  :eventName(admitted.type,'ARCANE_EVENT_DOM_OPTIONS_INVALID');
1872
1875
  for(const key of ['bubbles','composed','cancelable']){
1873
- if(admitted[key]!==undefined&&typeof admitted[key]!=='boolean'){
1876
+ if(admitted[key]!==undefined&&!is.boolean(admitted[key])){
1874
1877
  throw eventAuthorityError('ARCANE_EVENT_DOM_OPTIONS_INVALID',undefined,TypeError);
1875
1878
  }
1876
1879
  }
1877
- if(!target||typeof target.dispatchEvent!=='function'
1878
- ||typeof globalThis.CustomEvent!=='function'){
1880
+ if(!target||!is.function(target.dispatchEvent)
1881
+ ||!is.function(globalThis.CustomEvent)){
1879
1882
  throw eventAuthorityError('ARCANE_EVENT_DOM_TARGET_INVALID',undefined,TypeError);
1880
1883
  }
1881
1884
  const compatibility=compatibilityByOccurrence.get(occurrence);
1882
1885
  let detail;
1883
- const compatibilityPrototype=compatibility&&typeof compatibility==='object'
1886
+ const compatibilityPrototype=compatibility&&is.object(compatibility)
1884
1887
  ?Object.getPrototypeOf(compatibility)
1885
1888
  :undefined;
1886
- if(compatibility&&typeof compatibility==='object'
1887
- &&!Array.isArray(compatibility)
1889
+ if(compatibility&&is.object(compatibility)
1890
+ &&!is.array(compatibility)
1888
1891
  &&(compatibilityPrototype===Object.prototype||compatibilityPrototype===null)){
1889
1892
  detail={};
1890
1893
  for(const key of Reflect.ownKeys(compatibility)){
@@ -1933,7 +1936,7 @@ function createArcaneEventAuthority(){
1933
1936
  function safeDirectOn(type,handler,once=false){
1934
1937
  const admittedType=type==='*'?'*':eventName(type);
1935
1938
  const admitted=eventListener(handler);
1936
- if(typeof once!=='boolean'){
1939
+ if(!is.boolean(once)){
1937
1940
  throw eventAuthorityError('ARCANE_EVENT_SUBSCRIPTION_OPTIONS_INVALID',undefined,TypeError);
1938
1941
  }
1939
1942
  const record={type:admittedType,identity:admitted.identity,wrapper:null};
@@ -2001,9 +2004,9 @@ function createArcaneEventAuthority(){
2001
2004
 
2002
2005
  function usableArcaneEventAuthority(value){
2003
2006
  return Boolean(value)
2004
- &&(typeof value==='object'||typeof value==='function')
2007
+ &&(is.object(value)||is.function(value))
2005
2008
  &&value.protocol===ARCANE_EVENT_AUTHORITY_PROTOCOL
2006
- &&ARCANE_EVENT_REQUIRED_AUTHORITY_API.every(name=>typeof value[name]==='function');
2009
+ &&ARCANE_EVENT_REQUIRED_AUTHORITY_API.every(name=>is.function(value[name]));
2007
2010
  }
2008
2011
 
2009
2012
  function installArcaneEventAuthority(){