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.
- package/CHANGELOG.md +44 -0
- package/README.md +42 -19
- package/bin/arcane-test.mjs +16 -13
- package/browser-runtime/ai/browser-speech-artifacts.mjs +41 -38
- package/browser-runtime/ai/browser-speech-providers.mjs +53 -46
- package/browser-runtime/ai/browser-wasm-llm-provider.mjs +127 -124
- package/browser-runtime/ai/browser-wasm.mjs +6 -3
- package/browser-runtime/ai/browser-wllama-runtime.mjs +26 -23
- package/browser-runtime/ai/model-controller.mjs +94 -91
- package/browser-runtime/ai/speech-worker-client.mjs +12 -9
- package/browser-runtime/ai/speech-worker-runtime.mjs +56 -53
- package/browser-runtime/dependencies/strong-type/index.js +207 -82
- package/browser-runtime/dependencies/strong-type/package.json +15 -6
- package/browser-runtime/dom-event-instrumentation.mjs +24 -20
- package/browser-runtime/event-manager.mjs +111 -108
- package/browser-runtime/speech-text.mjs +35 -0
- package/docs/architecture.md +1 -1
- package/docs/reference/README.md +8 -8
- package/docs/reference/ai/browser-speech.md +230 -16
- package/docs/reference/ai/twin-cloud.md +1 -1
- package/docs/reference/availability-and-normalization.md +42 -1
- package/docs/reference/cli.md +1 -1
- package/docs/reference/core/arcane-ai-contracts.md +1 -1
- package/docs/reference/inventory/package-api.json +60 -4
- package/docs/reference/inventory/runtime-components.json +2 -2
- package/docs/reference/inventory/runtime-modules.json +29 -31
- package/docs/reference/protocols.md +17 -13
- package/docs/reference/runtime-components.md +6 -5
- package/docs/reference/runtime-modules.md +212 -70
- package/docs/reference/sdk-api.md +197 -11
- package/examples/wasm-ai-demo/index.html +1 -0
- package/node_modules/event-pubsub/node_modules/strong-type/README.md +408 -0
- package/node_modules/event-pubsub/node_modules/strong-type/assets/strong-type-header.png +0 -0
- package/node_modules/event-pubsub/node_modules/strong-type/index.js +1151 -0
- package/node_modules/event-pubsub/node_modules/strong-type/licence +21 -0
- package/node_modules/event-pubsub/node_modules/strong-type/node.js +125 -0
- package/node_modules/event-pubsub/node_modules/strong-type/package.json +61 -0
- package/node_modules/strong-type/README.md +42 -24
- package/node_modules/strong-type/benchmark/core.js +324 -0
- package/node_modules/strong-type/index.js +207 -82
- package/node_modules/strong-type/package.json +14 -6
- package/package.json +4 -3
- package/runtime/arcane/components/app-bar.html +5 -2
- package/runtime/arcane/components/assistant-panel.html +5 -2
- package/runtime/arcane/components/chart.html +15 -12
- package/runtime/arcane/components/chat.html +118 -141
- package/runtime/arcane/components/dashboard-config.html +6 -3
- package/runtime/arcane/components/data-view.html +4 -1
- package/runtime/arcane/components/directory-picker.html +5 -2
- package/runtime/arcane/components/document-inspector.html +6 -3
- package/runtime/arcane/components/file-drop.html +5 -2
- package/runtime/arcane/components/file-inspector.html +9 -6
- package/runtime/arcane/components/file-manager.html +16 -13
- package/runtime/arcane/components/local-ai-status.html +5 -2
- package/runtime/arcane/components/markdown-document.html +14 -11
- package/runtime/arcane/components/markdown-editor.html +4 -1
- package/runtime/arcane/components/modal.html +4 -1
- package/runtime/arcane/components/output-panel.html +6 -3
- package/runtime/arcane/components/preferences-form.html +4 -1
- package/runtime/arcane/components/record-timeline.html +8 -5
- package/runtime/arcane/components/relationship-board.html +9 -6
- package/runtime/arcane/components/source-code-viewer.html +12 -9
- package/runtime/arcane/components/source-explanation.html +8 -5
- package/runtime/arcane/components/speech.html +24 -21
- package/runtime/arcane/components/summary-strip.html +4 -1
- package/runtime/arcane/components/task-progress.html +6 -3
- package/runtime/arcane/components/terminal-workspace.html +4 -1
- package/runtime/arcane/components/voice-transcription.html +11 -8
- package/runtime/arcane/components/web-navigator.html +5 -2
- package/runtime/arcane/entities/ApiModelRecord.js +5 -2
- package/runtime/arcane/entities/Calculation.js +5 -2
- package/runtime/arcane/entities/Chat.js +33 -33
- package/runtime/arcane/entities/CommunicationMessage.js +4 -1
- package/runtime/arcane/entities/CommunicationThread.js +4 -1
- package/runtime/arcane/entities/File.js +1 -1
- package/runtime/arcane/entities/Image.js +8 -5
- package/runtime/arcane/entities/IntentEnvelope.js +20 -17
- package/runtime/arcane/entities/Preference.js +9 -6
- package/runtime/arcane/entities/Theme.js +5 -2
- package/runtime/arcane/entities/User.js +11 -11
- package/runtime/arcane/entities/Weather.js +5 -2
- package/runtime/arcane/modules/AI.js +503 -187
- package/runtime/arcane/modules/AIPreferenceRuntime.js +5 -2
- package/runtime/arcane/modules/AIPreferenceTuple.js +9 -6
- package/runtime/arcane/modules/AIProviderRuntime.js +117 -92
- package/runtime/arcane/modules/AIResponseURLPolicy.js +148 -62
- package/runtime/arcane/modules/AIRuntimeState.js +29 -26
- package/runtime/arcane/modules/AnsiText.js +4 -1
- package/runtime/arcane/modules/ApiModelDatabase.js +22 -19
- package/runtime/arcane/modules/AppDataScope.js +8 -5
- package/runtime/arcane/modules/ArcaneCommunicationBridge.js +4 -1
- package/runtime/arcane/modules/ArcaneNavigationPolicy.js +8 -5
- package/runtime/arcane/modules/ArcaneNetworkPolicy.js +18 -15
- package/runtime/arcane/modules/AsyncBoundary.js +13 -10
- package/runtime/arcane/modules/BrowserTestSuite.js +19 -16
- package/runtime/arcane/modules/CalculatorEngine.js +5 -2
- package/runtime/arcane/modules/ChatRecords.js +18 -15
- package/runtime/arcane/modules/CommunicationAppController.js +9 -6
- package/runtime/arcane/modules/CommunicationHub.js +9 -6
- package/runtime/arcane/modules/CommunicationPreferences.js +4 -1
- package/runtime/arcane/modules/CommunicationProviderRegistry.js +4 -1
- package/runtime/arcane/modules/ComponentContracts.js +56 -53
- package/runtime/arcane/modules/ConfiguredAIChatSession.js +30 -27
- package/runtime/arcane/modules/ConversationActionItems.js +15 -12
- package/runtime/arcane/modules/ConversationClosingReport.js +11 -8
- package/runtime/arcane/modules/ConversationTimebox.js +28 -25
- package/runtime/arcane/modules/CoreLocalModelCatalog.js +17 -14
- package/runtime/arcane/modules/DBLS.js +7 -4
- package/runtime/arcane/modules/DBOPFS.js +7 -7
- package/runtime/arcane/modules/DBOPFSDocumentLibrary.js +34 -31
- package/runtime/arcane/modules/DevelopmentWorkspace.js +4 -1
- package/runtime/arcane/modules/DirectoryPicker.js +8 -5
- package/runtime/arcane/modules/DocumentLexicalSearch.js +11 -8
- package/runtime/arcane/modules/DocumentNavigation.js +7 -4
- package/runtime/arcane/modules/Errors.js +28 -25
- package/runtime/arcane/modules/HTMLImport.js +7 -4
- package/runtime/arcane/modules/IsolatedModelQuestionRunner.js +15 -12
- package/runtime/arcane/modules/LocalAIReadiness.js +21 -18
- package/runtime/arcane/modules/LocalAIReadinessController.js +6 -3
- package/runtime/arcane/modules/MD.js +1 -1
- package/runtime/arcane/modules/Mail.js +46 -43
- package/runtime/arcane/modules/MailOutbox.mjs +48 -45
- package/runtime/arcane/modules/MailTransport.mjs +29 -26
- package/runtime/arcane/modules/MarkdownSpeech.js +1 -50
- package/runtime/arcane/modules/MemoryRecords.js +7 -4
- package/runtime/arcane/modules/MessageAdvisory.js +6 -3
- package/runtime/arcane/modules/ModelDefinition.js +7 -4
- package/runtime/arcane/modules/Ollama.js +6 -3
- package/runtime/arcane/modules/OllamaModelIdentifier.js +4 -1
- package/runtime/arcane/modules/OpenMeteoWeatherProvider.js +18 -15
- package/runtime/arcane/modules/PersistentAIChatSession.js +33 -30
- package/runtime/arcane/modules/PreferenceStore.js +20 -17
- package/runtime/arcane/modules/PreparedSpeech.js +485 -0
- package/runtime/arcane/modules/Questionnaire.js +6 -3
- package/runtime/arcane/modules/RecordLinkIndex.js +4 -1
- package/runtime/arcane/modules/RecordPassageIndex.js +9 -6
- package/runtime/arcane/modules/RecordReviewStore.js +12 -9
- package/runtime/arcane/modules/RiskSignalAnalyzer.js +4 -1
- package/runtime/arcane/modules/ScopedOPFSCache.js +6 -3
- package/runtime/arcane/modules/ScreenCapture.js +20 -17
- package/runtime/arcane/modules/SpeechPlayback.js +61 -28
- package/runtime/arcane/modules/StaticDocumentCatalog.js +33 -30
- package/runtime/arcane/modules/SystemAppearance.js +5 -2
- package/runtime/arcane/modules/SystemToolRegistry.js +6 -3
- package/runtime/arcane/modules/TerminalClient.js +14 -11
- package/runtime/arcane/modules/TerminalCommandRegistry.js +4 -1
- package/runtime/arcane/modules/ThemeBootstrap.js +9 -6
- package/runtime/arcane/modules/ThemeManager.js +5 -2
- package/runtime/arcane/modules/TimeGuard.js +1 -1
- package/runtime/arcane/modules/ToolCallRouter.js +11 -8
- package/runtime/arcane/modules/WaitForComponent.js +19 -16
- package/runtime/arcane/modules/YouTubeMedia.js +4 -1
- package/runtime/strong-type/index.js +1276 -352
- package/runtime/strong-type/package.json +69 -45
- package/src/app-descriptor.mjs +17 -14
- package/src/application-tests.mjs +4 -1
- package/src/cli/main.mjs +8 -5
- package/src/constants.mjs +4 -1
- package/src/dev-server.mjs +8 -5
- package/src/doctor.mjs +5 -2
- package/src/dom-event-instrumentation.mjs +24 -20
- package/src/errors.mjs +7 -3
- package/src/event-manager.mjs +111 -108
- package/src/event-queue.mjs +8 -5
- package/src/events.mjs +12 -9
- package/src/import-map.mjs +36 -27
- package/src/installed-sdk-runtime.mjs +4 -1
- package/src/integrated-provider-loader.mjs +9 -6
- package/src/mail-credentials.mjs +16 -13
- package/src/mail-server.mjs +53 -50
- package/src/mail.mjs +18 -15
- package/src/native-plan.mjs +12 -9
- package/src/native-provider-loader.mjs +7 -4
- package/src/packager/core.mjs +18 -15
- package/src/process.mjs +6 -3
- package/src/release-bundle.mjs +14 -11
- package/src/runtime.mjs +4 -1
- package/src/scaffold.mjs +9 -6
- package/src/sdk-browser-runtime.mjs +4 -1
- package/src/source-server.mjs +17 -14
- package/src/targets/index.mjs +5 -2
- package/src/templates/workspace-template.mjs +13 -6
- package/src/testing-loader.mjs +7 -4
- package/src/testing.mjs +10 -7
- package/src/toolchain.mjs +13 -10
- package/src/update-check.mjs +9 -6
- package/src/workspace-operation-lock.mjs +14 -11
- package/src/workspace-runtime.mjs +4 -1
- package/src/workspace.mjs +17 -14
- package/runtime/arcane/modules/AIResponseLength.js +0 -32
package/src/event-manager.mjs
CHANGED
|
@@ -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(
|
|
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(
|
|
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&&(
|
|
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(
|
|
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(
|
|
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(!
|
|
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
|
|
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
|
|
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||
|
|
217
|
-
if(
|
|
218
|
-
if(
|
|
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(
|
|
224
|
+
if(is.bigint(value))return taggedSnapshot('bigint',[[
|
|
222
225
|
'value',safeString(value.toString())
|
|
223
226
|
]]);
|
|
224
|
-
if(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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&&
|
|
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
|
|
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
|
|
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
|
|
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(!
|
|
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
|
|
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||
|
|
480
|
-
if(
|
|
481
|
-
if(!
|
|
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(
|
|
485
|
-
if(!value
|
|
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(
|
|
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
|
|
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(
|
|
537
|
+
if(!is.string(value))invalidStack(label);
|
|
535
538
|
const milliseconds=Date.parse(value);
|
|
536
|
-
if(!
|
|
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(
|
|
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(!
|
|
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(
|
|
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
|
-
&&(!
|
|
582
|
+
&&(!is.safeInteger(fields.parentSequence)||fields.parentSequence<1
|
|
580
583
|
||fields.parentSequence>=fields.sequence)){
|
|
581
584
|
invalidStack(`${label} parent`);
|
|
582
585
|
}
|
|
583
|
-
if(!
|
|
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
|
|
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
|
-
|
|
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
|
|
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(
|
|
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
|
-
|
|
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(
|
|
721
|
+
if(!is.boolean(timeTravel)){
|
|
719
722
|
throw new TypeError('EventManager flags must be boolean values.');
|
|
720
723
|
}
|
|
721
|
-
if(
|
|
724
|
+
if(!is.function(clock)||!is.function(now)){
|
|
722
725
|
throw new TypeError('EventManager clocks must be functions.');
|
|
723
726
|
}
|
|
724
|
-
if(
|
|
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
|
|
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(
|
|
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&&
|
|
807
|
-
&&!
|
|
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:
|
|
829
|
+
source:is.string(safeMetadata.source)&&safeMetadata.source
|
|
827
830
|
?safeString(safeMetadata.source)
|
|
828
831
|
:'application',
|
|
829
|
-
category:
|
|
832
|
+
category:is.string(safeMetadata.category)&&safeMetadata.category
|
|
830
833
|
?safeString(safeMetadata.category)
|
|
831
834
|
:null,
|
|
832
|
-
correlationId:
|
|
835
|
+
correlationId:is.string(safeMetadata.correlationId)
|
|
833
836
|
&&safeMetadata.correlationId
|
|
834
837
|
?safeString(safeMetadata.correlationId):null,
|
|
835
|
-
causationId:
|
|
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:
|
|
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&&(
|
|
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(
|
|
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(!
|
|
989
|
-
||!
|
|
990
|
-
||(type!==null
|
|
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(!
|
|
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(!
|
|
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(!
|
|
1031
|
-
||!
|
|
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(
|
|
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
|
|
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=
|
|
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=
|
|
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(
|
|
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
|
|
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(
|
|
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
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
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(
|
|
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&&
|
|
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(
|
|
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&&
|
|
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||(
|
|
1207
|
-
if(
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
1287
|
+
if(!value||!is.object(value)||is.array(value))throw new TypeError();
|
|
1285
1288
|
const EventConstructor=globalThis.Event;
|
|
1286
|
-
if(
|
|
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:
|
|
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:
|
|
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(
|
|
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&&
|
|
1382
|
-
&&!
|
|
1383
|
-
const publicRecord=publicDetail&&
|
|
1384
|
-
&&!
|
|
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&&
|
|
1661
|
-
&&
|
|
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||(
|
|
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(!
|
|
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
|
-
|
|
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&&(
|
|
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
|
|
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
|
|
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
|
|
1878
|
-
|
|
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&&
|
|
1886
|
+
const compatibilityPrototype=compatibility&&is.object(compatibility)
|
|
1884
1887
|
?Object.getPrototypeOf(compatibility)
|
|
1885
1888
|
:undefined;
|
|
1886
|
-
if(compatibility&&
|
|
1887
|
-
&&!
|
|
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(
|
|
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
|
-
&&(
|
|
2007
|
+
&&(is.object(value)||is.function(value))
|
|
2005
2008
|
&&value.protocol===ARCANE_EVENT_AUTHORITY_PROTOCOL
|
|
2006
|
-
&&ARCANE_EVENT_REQUIRED_AUTHORITY_API.every(name=>
|
|
2009
|
+
&&ARCANE_EVENT_REQUIRED_AUTHORITY_API.every(name=>is.function(value[name]));
|
|
2007
2010
|
}
|
|
2008
2011
|
|
|
2009
2012
|
function installArcaneEventAuthority(){
|