arcane-os 0.5.17 → 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 +24 -0
- package/README.md +9 -9
- 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 +46 -43
- 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 +5 -1
- package/docs/reference/ai/browser-speech.md +198 -5
- package/docs/reference/availability-and-normalization.md +40 -0
- package/docs/reference/inventory/package-api.json +1 -1
- package/docs/reference/inventory/runtime-components.json +1 -1
- package/docs/reference/inventory/runtime-modules.json +20 -24
- package/docs/reference/protocols.md +1 -1
- package/docs/reference/runtime-modules.md +125 -35
- package/docs/reference/sdk-api.md +23 -7
- 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 +3 -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 +117 -138
- 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 +491 -165
- package/runtime/arcane/modules/AIPreferenceRuntime.js +5 -2
- package/runtime/arcane/modules/AIPreferenceTuple.js +9 -6
- package/runtime/arcane/modules/AIProviderRuntime.js +88 -85
- 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/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 +29 -26
- 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 +35 -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
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import Is from './dependencies/strong-type/index.js';
|
|
1
2
|
import EventPubSub from 'event-pubsub';
|
|
2
3
|
import {arcaneLogging} from './logging.mjs';
|
|
3
4
|
import {createDOMInstrumentation} from './dom-event-instrumentation.mjs';
|
|
4
5
|
|
|
6
|
+
const is=new Is(false);
|
|
7
|
+
|
|
5
8
|
export {
|
|
6
9
|
createDOMInstrumentation,
|
|
7
10
|
DEFAULT_DOM_EVENT_TYPES,
|
|
@@ -146,7 +149,7 @@ function taggedSnapshot(type,entries=[]){
|
|
|
146
149
|
function safeDataString(value,key,{fallback=''}={}){
|
|
147
150
|
try{
|
|
148
151
|
const current=Reflect.get(value,key);
|
|
149
|
-
if(
|
|
152
|
+
if(is.string(current))return current;
|
|
150
153
|
}catch{}
|
|
151
154
|
return fallback;
|
|
152
155
|
}
|
|
@@ -154,7 +157,7 @@ function safeDataString(value,key,{fallback=''}={}){
|
|
|
154
157
|
function regexpFlags(value){
|
|
155
158
|
let result='';
|
|
156
159
|
for(const [flag,getter] of REGEXP_FLAG_GETTERS){
|
|
157
|
-
if(
|
|
160
|
+
if(is.function(getter)&&getter.call(value))result+=flag;
|
|
158
161
|
}
|
|
159
162
|
return result;
|
|
160
163
|
}
|
|
@@ -166,7 +169,7 @@ function safeString(value){
|
|
|
166
169
|
function safeErrorText(error){
|
|
167
170
|
let text='Snapshot capture failed.';
|
|
168
171
|
try{
|
|
169
|
-
if(error!==null&&(
|
|
172
|
+
if(error!==null&&(is.object(error)||is.function(error))){
|
|
170
173
|
const message=safeDataString(error,'message');
|
|
171
174
|
if(message)text=message;
|
|
172
175
|
}else if(error!==undefined){
|
|
@@ -178,34 +181,34 @@ function safeErrorText(error){
|
|
|
178
181
|
}
|
|
179
182
|
|
|
180
183
|
function sessionIdentifier(){
|
|
181
|
-
if(
|
|
184
|
+
if(is.function(globalThis.crypto?.randomUUID))return globalThis.crypto.randomUUID();
|
|
182
185
|
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
183
186
|
}
|
|
184
187
|
|
|
185
188
|
function clockDate(clock){
|
|
186
189
|
const value=clock();
|
|
187
190
|
const result=value instanceof Date?new Date(value.getTime()):new Date(value);
|
|
188
|
-
if(
|
|
191
|
+
if(is.nan(result.getTime()))throw new TypeError('The event clock returned an invalid timestamp.');
|
|
189
192
|
return result;
|
|
190
193
|
}
|
|
191
194
|
|
|
192
195
|
function monotonicValue(now){
|
|
193
196
|
const value=Number(now());
|
|
194
|
-
if(!
|
|
197
|
+
if(!is.finite(value)||value<0){
|
|
195
198
|
throw new TypeError('The monotonic event clock returned an invalid value.');
|
|
196
199
|
}
|
|
197
200
|
return value;
|
|
198
201
|
}
|
|
199
202
|
|
|
200
203
|
function defaultMonotonicClock(){
|
|
201
|
-
return
|
|
204
|
+
return is.function(globalThis.performance?.now)
|
|
202
205
|
?globalThis.performance.now()
|
|
203
206
|
:Date.now();
|
|
204
207
|
}
|
|
205
208
|
|
|
206
209
|
function sourceStack(){
|
|
207
210
|
const stack=new Error('Arcane event source').stack;
|
|
208
|
-
return
|
|
211
|
+
return is.string(stack)?stack:null;
|
|
209
212
|
}
|
|
210
213
|
|
|
211
214
|
function snapshot(value,{
|
|
@@ -214,20 +217,20 @@ function snapshot(value,{
|
|
|
214
217
|
depth=0,
|
|
215
218
|
seen=new Map()
|
|
216
219
|
}={}){
|
|
217
|
-
if(value===null||value===undefined||
|
|
218
|
-
if(
|
|
219
|
-
if(
|
|
220
|
+
if(value===null||value===undefined||is.boolean(value))return value;
|
|
221
|
+
if(is.string(value))return safeString(value);
|
|
222
|
+
if(is.number(value))return is.finite(value)
|
|
220
223
|
?value
|
|
221
224
|
:taggedSnapshot('number',[['value',String(value)]]);
|
|
222
|
-
if(
|
|
225
|
+
if(is.bigint(value))return taggedSnapshot('bigint',[[
|
|
223
226
|
'value',safeString(value.toString())
|
|
224
227
|
]]);
|
|
225
|
-
if(
|
|
228
|
+
if(is.symbol(value))return taggedSnapshot('symbol',[[
|
|
226
229
|
'value',value.description===undefined
|
|
227
230
|
?null
|
|
228
231
|
:safeString(value.description)
|
|
229
232
|
]]);
|
|
230
|
-
if(
|
|
233
|
+
if(is.function(value)){
|
|
231
234
|
const name=safeDataString(value,'name');
|
|
232
235
|
return taggedSnapshot('function',[[
|
|
233
236
|
'name',name?safeString(name):null
|
|
@@ -276,7 +279,7 @@ function snapshot(value,{
|
|
|
276
279
|
}
|
|
277
280
|
return taggedSnapshot('error',entries);
|
|
278
281
|
}
|
|
279
|
-
if(
|
|
282
|
+
if(is.array(value)){
|
|
280
283
|
const result=[];
|
|
281
284
|
for(let index=0;index<value.length;index+=1){
|
|
282
285
|
let item;
|
|
@@ -307,7 +310,7 @@ function snapshot(value,{
|
|
|
307
310
|
}
|
|
308
311
|
return taggedSnapshot('set',[['values',values]]);
|
|
309
312
|
}
|
|
310
|
-
if(
|
|
313
|
+
if(is.arrayBufferView(value)){
|
|
311
314
|
const dataView=value instanceof DataView;
|
|
312
315
|
let values;
|
|
313
316
|
let type='DataView';
|
|
@@ -335,7 +338,7 @@ function snapshot(value,{
|
|
|
335
338
|
|
|
336
339
|
const result=snapshotObject();
|
|
337
340
|
const properties=Reflect.ownKeys(value).filter(property=>{
|
|
338
|
-
if(
|
|
341
|
+
if(!is.string(property))return false;
|
|
339
342
|
const descriptor=Object.getOwnPropertyDescriptor(value,property);
|
|
340
343
|
return descriptor?.enumerable===true;
|
|
341
344
|
});
|
|
@@ -372,13 +375,13 @@ function completeSnapshot(value,options){
|
|
|
372
375
|
|
|
373
376
|
function completeErrorSnapshot(value,options){
|
|
374
377
|
const captured=completeSnapshot(value,options);
|
|
375
|
-
if(captured&&
|
|
378
|
+
if(captured&&is.object(captured)&&!is.array(captured))return captured;
|
|
376
379
|
return taggedSnapshot('thrown',[['value',captured]]);
|
|
377
380
|
}
|
|
378
381
|
|
|
379
382
|
function normalizeMetadata(metadata){
|
|
380
383
|
if(metadata===undefined)return {};
|
|
381
|
-
if(metadata===null
|
|
384
|
+
if(metadata===null||!is.object(metadata)||is.array(metadata)){
|
|
382
385
|
throw new TypeError('Event instrumentation metadata must be an object.');
|
|
383
386
|
}
|
|
384
387
|
return metadata;
|
|
@@ -418,11 +421,11 @@ function invalidStack(label){
|
|
|
418
421
|
|
|
419
422
|
function exactDataObject(value,expectedKeys,label){
|
|
420
423
|
try{
|
|
421
|
-
if(!value
|
|
424
|
+
if(!value||!is.object(value)||is.array(value))invalidStack(label);
|
|
422
425
|
const prototype=Object.getPrototypeOf(value);
|
|
423
426
|
if(prototype!==Object.prototype&&prototype!==null)invalidStack(label);
|
|
424
427
|
const keys=Reflect.ownKeys(value);
|
|
425
|
-
if(keys.length!==expectedKeys.length||keys.some(key
|
|
428
|
+
if(keys.length!==expectedKeys.length||keys.some(key=>!is.string(key))){
|
|
426
429
|
invalidStack(label);
|
|
427
430
|
}
|
|
428
431
|
const expected=new Set(expectedKeys);
|
|
@@ -449,11 +452,11 @@ function exactDataObject(value,expectedKeys,label){
|
|
|
449
452
|
|
|
450
453
|
function denseArrayValues(value,label){
|
|
451
454
|
try{
|
|
452
|
-
if(!
|
|
455
|
+
if(!is.array(value)||!is.safeInteger(value.length)||value.length<0){
|
|
453
456
|
invalidStack(label);
|
|
454
457
|
}
|
|
455
458
|
const keys=Reflect.ownKeys(value);
|
|
456
|
-
if(keys.some(key
|
|
459
|
+
if(keys.some(key=>!is.string(key)))invalidStack(label);
|
|
457
460
|
const expected=new Set(['length']);
|
|
458
461
|
for(let index=0;index<value.length;index+=1)expected.add(String(index));
|
|
459
462
|
if(keys.length!==expected.size||keys.some(key=>!expected.has(key)))invalidStack(label);
|
|
@@ -477,17 +480,17 @@ function cloneImportedValue(value,{
|
|
|
477
480
|
depth=0,
|
|
478
481
|
seen=new WeakSet()
|
|
479
482
|
}){
|
|
480
|
-
if(value===null||
|
|
481
|
-
if(
|
|
482
|
-
if(!
|
|
483
|
+
if(value===null||is.boolean(value))return value;
|
|
484
|
+
if(is.number(value)){
|
|
485
|
+
if(!is.finite(value))invalidStack(`Event stack value at ${path}`);
|
|
483
486
|
return value;
|
|
484
487
|
}
|
|
485
|
-
if(
|
|
486
|
-
if(!value
|
|
488
|
+
if(is.string(value))return value;
|
|
489
|
+
if(!value||!is.object(value))invalidStack(`Event stack value at ${path}`);
|
|
487
490
|
if(seen.has(value))invalidStack(`Event stack value at ${path}`);
|
|
488
491
|
seen.add(value);
|
|
489
492
|
|
|
490
|
-
if(
|
|
493
|
+
if(is.array(value)){
|
|
491
494
|
const items=denseArrayValues(value,`Event stack array at ${path}`);
|
|
492
495
|
return items.map((item,index)=>cloneImportedValue(item,{
|
|
493
496
|
path:`${path}[${String(index)}]`,
|
|
@@ -505,7 +508,7 @@ function cloneImportedValue(value,{
|
|
|
505
508
|
throw new TypeError(`Event stack value at ${path} is invalid.`,{cause:error});
|
|
506
509
|
}
|
|
507
510
|
if((prototype!==Object.prototype&&prototype!==null)
|
|
508
|
-
||keys.some(key
|
|
511
|
+
||keys.some(key=>!is.string(key))){
|
|
509
512
|
invalidStack(`Event stack value at ${path}`);
|
|
510
513
|
}
|
|
511
514
|
const result=dataObject();
|
|
@@ -532,9 +535,9 @@ function cloneImportedValue(value,{
|
|
|
532
535
|
}
|
|
533
536
|
|
|
534
537
|
function canonicalTimestamp(value,label){
|
|
535
|
-
if(
|
|
538
|
+
if(!is.string(value))invalidStack(label);
|
|
536
539
|
const milliseconds=Date.parse(value);
|
|
537
|
-
if(!
|
|
540
|
+
if(!is.finite(milliseconds)||new Date(milliseconds).toISOString()!==value){
|
|
538
541
|
invalidStack(label);
|
|
539
542
|
}
|
|
540
543
|
return milliseconds;
|
|
@@ -542,7 +545,7 @@ function canonicalTimestamp(value,label){
|
|
|
542
545
|
|
|
543
546
|
function recordString(value,label,{nullable=false,empty=true}={}){
|
|
544
547
|
if(nullable&&value===null)return null;
|
|
545
|
-
if(
|
|
548
|
+
if(!is.string(value)||(!empty&&!value)){
|
|
546
549
|
invalidStack(label);
|
|
547
550
|
}
|
|
548
551
|
return value;
|
|
@@ -556,12 +559,12 @@ function validateRecord(record,index,{
|
|
|
556
559
|
if(fields.protocol!==ARCANE_EVENT_STACK_PROTOCOL||fields.sessionId!==sessionId){
|
|
557
560
|
invalidStack(label);
|
|
558
561
|
}
|
|
559
|
-
if(!
|
|
562
|
+
if(!is.safeInteger(fields.sequence)||fields.sequence<1
|
|
560
563
|
||fields.id!==`${sessionId}:${String(fields.sequence)}`){
|
|
561
564
|
invalidStack(label);
|
|
562
565
|
}
|
|
563
566
|
const timestampMs=canonicalTimestamp(fields.timestamp,`${label} timestamp`);
|
|
564
|
-
if(
|
|
567
|
+
if(!is.number(fields.monotonicMs)||!is.finite(fields.monotonicMs)
|
|
565
568
|
||fields.monotonicMs<0){
|
|
566
569
|
invalidStack(`${label} monotonic timing`);
|
|
567
570
|
}
|
|
@@ -577,11 +580,11 @@ function validateRecord(record,index,{
|
|
|
577
580
|
nullable:true,empty:false
|
|
578
581
|
});
|
|
579
582
|
if(fields.parentSequence!==null
|
|
580
|
-
&&(!
|
|
583
|
+
&&(!is.safeInteger(fields.parentSequence)||fields.parentSequence<1
|
|
581
584
|
||fields.parentSequence>=fields.sequence)){
|
|
582
585
|
invalidStack(`${label} parent`);
|
|
583
586
|
}
|
|
584
|
-
if(!
|
|
587
|
+
if(!is.safeInteger(fields.depth)||fields.depth<0
|
|
585
588
|
||(fields.parentSequence===null)!==(fields.depth===0)){
|
|
586
589
|
invalidStack(`${label} depth`);
|
|
587
590
|
}
|
|
@@ -599,7 +602,7 @@ function validateRecord(record,index,{
|
|
|
599
602
|
depth:0,
|
|
600
603
|
seen:new WeakSet()
|
|
601
604
|
});
|
|
602
|
-
if(!metadata
|
|
605
|
+
if(!metadata||!is.object(metadata)||is.array(metadata)){
|
|
603
606
|
invalidStack(`${label} metadata`);
|
|
604
607
|
}
|
|
605
608
|
|
|
@@ -613,7 +616,7 @@ function validateRecord(record,index,{
|
|
|
613
616
|
}else{
|
|
614
617
|
const completedAtMs=canonicalTimestamp(fields.completedAt,`${label} completion timestamp`);
|
|
615
618
|
if(completedAtMs<timestampMs
|
|
616
|
-
|
|
619
|
+
||!is.number(fields.durationMs)||!is.finite(fields.durationMs)
|
|
617
620
|
||fields.durationMs<0){
|
|
618
621
|
invalidStack(`${label} completion timing`);
|
|
619
622
|
}
|
|
@@ -627,7 +630,7 @@ function validateRecord(record,index,{
|
|
|
627
630
|
depth:0,
|
|
628
631
|
seen:new WeakSet()
|
|
629
632
|
});
|
|
630
|
-
if(!error
|
|
633
|
+
if(!error||!is.object(error)||is.array(error)){
|
|
631
634
|
invalidStack(`${label} error`);
|
|
632
635
|
}
|
|
633
636
|
}
|
|
@@ -659,14 +662,14 @@ function validateRecord(record,index,{
|
|
|
659
662
|
|
|
660
663
|
export function parseEventStack(source){
|
|
661
664
|
let document=source;
|
|
662
|
-
if(
|
|
665
|
+
if(is.string(source)){
|
|
663
666
|
try{document=JSON.parse(source);}catch(error){
|
|
664
667
|
throw new TypeError('The event stack is not valid JSON.',{cause:error});
|
|
665
668
|
}
|
|
666
669
|
}
|
|
667
670
|
const fields=exactDataObject(document,DOCUMENT_KEYS,'The event stack document');
|
|
668
671
|
if(fields.protocol!==ARCANE_EVENT_STACK_PROTOCOL
|
|
669
|
-
|
|
672
|
+
||!is.string(fields.sessionId)||!fields.sessionId){
|
|
670
673
|
invalidStack('The event stack document');
|
|
671
674
|
}
|
|
672
675
|
canonicalTimestamp(fields.createdAt,'The event stack creation timestamp');
|
|
@@ -716,13 +719,13 @@ export class EventManager{
|
|
|
716
719
|
now=defaultMonotonicClock,
|
|
717
720
|
sessionId=sessionIdentifier()
|
|
718
721
|
}={}){
|
|
719
|
-
if(
|
|
722
|
+
if(!is.boolean(timeTravel)){
|
|
720
723
|
throw new TypeError('EventManager flags must be boolean values.');
|
|
721
724
|
}
|
|
722
|
-
if(
|
|
725
|
+
if(!is.function(clock)||!is.function(now)){
|
|
723
726
|
throw new TypeError('EventManager clocks must be functions.');
|
|
724
727
|
}
|
|
725
|
-
if(
|
|
728
|
+
if(!is.string(sessionId)||!sessionId){
|
|
726
729
|
throw new TypeError('EventManager sessionId must be a non-empty string.');
|
|
727
730
|
}
|
|
728
731
|
this.#clock=clock;
|
|
@@ -784,14 +787,14 @@ export class EventManager{
|
|
|
784
787
|
}
|
|
785
788
|
|
|
786
789
|
forward(event,metadata={}){
|
|
787
|
-
if(!event
|
|
790
|
+
if(!event||!is.object(event)||is.array(event)||!is.string(event.type)){
|
|
788
791
|
throw new TypeError('Forwarded events must be objects with a string type.');
|
|
789
792
|
}
|
|
790
793
|
return this.instrument(event.type,event,metadata);
|
|
791
794
|
}
|
|
792
795
|
|
|
793
796
|
#dispatch(type,payload,metadata){
|
|
794
|
-
if(
|
|
797
|
+
if(!is.string(type)){
|
|
795
798
|
this.#bus.emit(type,...payload);
|
|
796
799
|
return this;
|
|
797
800
|
}
|
|
@@ -804,8 +807,8 @@ export class EventManager{
|
|
|
804
807
|
startedMonotonic=monotonicValue(this.#now);
|
|
805
808
|
const payloadSnapshot=completeSnapshot(payload);
|
|
806
809
|
const metadataSnapshot=completeSnapshot(metadata);
|
|
807
|
-
const safeMetadata=metadataSnapshot&&
|
|
808
|
-
&&!
|
|
810
|
+
const safeMetadata=metadataSnapshot&&is.object(metadataSnapshot)
|
|
811
|
+
&&!is.array(metadataSnapshot)
|
|
809
812
|
?metadataSnapshot
|
|
810
813
|
:snapshotObject();
|
|
811
814
|
const sequence=this.#sequence+1;
|
|
@@ -824,23 +827,23 @@ export class EventManager{
|
|
|
824
827
|
timestamp,
|
|
825
828
|
monotonicMs:startedMonotonic,
|
|
826
829
|
type:safeString(type),
|
|
827
|
-
source:
|
|
830
|
+
source:is.string(safeMetadata.source)&&safeMetadata.source
|
|
828
831
|
?safeString(safeMetadata.source)
|
|
829
832
|
:'application',
|
|
830
|
-
category:
|
|
833
|
+
category:is.string(safeMetadata.category)&&safeMetadata.category
|
|
831
834
|
?safeString(safeMetadata.category)
|
|
832
835
|
:null,
|
|
833
|
-
correlationId:
|
|
836
|
+
correlationId:is.string(safeMetadata.correlationId)
|
|
834
837
|
&&safeMetadata.correlationId
|
|
835
838
|
?safeString(safeMetadata.correlationId):null,
|
|
836
|
-
causationId:
|
|
839
|
+
causationId:is.string(safeMetadata.causationId)
|
|
837
840
|
&&safeMetadata.causationId
|
|
838
841
|
?safeString(safeMetadata.causationId)
|
|
839
842
|
:(parentSequence===null?null:`${this.#sessionId}:${parentSequence}`),
|
|
840
843
|
parentSequence,
|
|
841
844
|
depth:this.#activeDispatch.length,
|
|
842
845
|
stack,
|
|
843
|
-
payload:
|
|
846
|
+
payload:is.array(payloadSnapshot)
|
|
844
847
|
?payloadSnapshot
|
|
845
848
|
:[payloadSnapshot],
|
|
846
849
|
metadata:safeMetadata,
|
|
@@ -945,7 +948,7 @@ export class EventManager{
|
|
|
945
948
|
if(replacement.active||replacement.cleanupPending){
|
|
946
949
|
this.#domInstrumentation=replacement;
|
|
947
950
|
try{
|
|
948
|
-
if(error&&(
|
|
951
|
+
if(error&&(is.object(error)||is.function(error))){
|
|
949
952
|
Object.defineProperty(error,'domInstrumentation',{
|
|
950
953
|
value:replacement,
|
|
951
954
|
enumerable:false,
|
|
@@ -973,7 +976,7 @@ export class EventManager{
|
|
|
973
976
|
}
|
|
974
977
|
|
|
975
978
|
clearHistory({newSession=true}={}){
|
|
976
|
-
if(
|
|
979
|
+
if(!is.boolean(newSession))throw new TypeError('newSession must be boolean.');
|
|
977
980
|
if(this.#activeDispatch.length||this.#replaying){
|
|
978
981
|
throw new Error('Event history cannot be cleared during dispatch or playback.');
|
|
979
982
|
}
|
|
@@ -986,9 +989,9 @@ export class EventManager{
|
|
|
986
989
|
}
|
|
987
990
|
|
|
988
991
|
getEventStack({fromSequence=1,toSequence=Number.MAX_SAFE_INTEGER,type=null}={}){
|
|
989
|
-
if(!
|
|
990
|
-
||!
|
|
991
|
-
||(type!==null
|
|
992
|
+
if(!is.safeInteger(fromSequence)||fromSequence<1
|
|
993
|
+
||!is.safeInteger(toSequence)||toSequence<fromSequence
|
|
994
|
+
||(type!==null&&!is.string(type))){
|
|
992
995
|
throw new TypeError('The event stack range is invalid.');
|
|
993
996
|
}
|
|
994
997
|
return this.#history.filter(record=>
|
|
@@ -998,7 +1001,7 @@ export class EventManager{
|
|
|
998
1001
|
}
|
|
999
1002
|
|
|
1000
1003
|
exportStack({space=2}={}){
|
|
1001
|
-
if(!
|
|
1004
|
+
if(!is.safeInteger(space)||space<0||space>10){
|
|
1002
1005
|
throw new RangeError('Event stack JSON indentation must be from 0 through 10.');
|
|
1003
1006
|
}
|
|
1004
1007
|
return JSON.stringify({
|
|
@@ -1010,7 +1013,7 @@ export class EventManager{
|
|
|
1010
1013
|
}
|
|
1011
1014
|
|
|
1012
1015
|
seek(sequence){
|
|
1013
|
-
if(!
|
|
1016
|
+
if(!is.safeInteger(sequence)||sequence<0||sequence>this.#sequence){
|
|
1014
1017
|
throw new RangeError('The time-travel sequence is outside this event stack.');
|
|
1015
1018
|
}
|
|
1016
1019
|
this.#cursor=sequence;
|
|
@@ -1028,17 +1031,17 @@ export class EventManager{
|
|
|
1028
1031
|
signal,
|
|
1029
1032
|
onRecord
|
|
1030
1033
|
}={}){
|
|
1031
|
-
if(!
|
|
1032
|
-
||!
|
|
1034
|
+
if(!is.safeInteger(fromSequence)||fromSequence<1
|
|
1035
|
+
||!is.safeInteger(toSequence)||toSequence<fromSequence){
|
|
1033
1036
|
throw new TypeError('The playback range is invalid.');
|
|
1034
1037
|
}
|
|
1035
|
-
if(
|
|
1038
|
+
if(!is.number(speed)||!is.finite(speed)||speed<0){
|
|
1036
1039
|
throw new RangeError('Playback speed must be zero or a positive finite number.');
|
|
1037
1040
|
}
|
|
1038
1041
|
if(!['review','events','none'].includes(mode)){
|
|
1039
1042
|
throw new TypeError('Playback mode must be review, events, or none.');
|
|
1040
1043
|
}
|
|
1041
|
-
if(onRecord!==undefined
|
|
1044
|
+
if(onRecord!==undefined&&!is.function(onRecord)){
|
|
1042
1045
|
throw new TypeError('onRecord must be a function.');
|
|
1043
1046
|
}
|
|
1044
1047
|
if(this.#replaying)throw new Error('Event playback is already active.');
|
|
@@ -1066,13 +1069,13 @@ export class EventManager{
|
|
|
1066
1069
|
if(signal?.aborted)throw abortError(signal.reason);
|
|
1067
1070
|
if(speed>0&&(previousTimestamp!==null||previousMonotonic!==null)){
|
|
1068
1071
|
const monotonic=Number(record.monotonicMs);
|
|
1069
|
-
const difference=
|
|
1072
|
+
const difference=is.finite(monotonic)&&previousMonotonic!==null
|
|
1070
1073
|
?Math.max(0,monotonic-previousMonotonic)
|
|
1071
1074
|
:Math.max(0,Date.parse(record.timestamp)-previousTimestamp);
|
|
1072
1075
|
await wait(difference/speed,signal);
|
|
1073
1076
|
}
|
|
1074
1077
|
previousTimestamp=Date.parse(record.timestamp);
|
|
1075
|
-
previousMonotonic=
|
|
1078
|
+
previousMonotonic=is.finite(Number(record.monotonicMs))
|
|
1076
1079
|
?Number(record.monotonicMs)
|
|
1077
1080
|
:null;
|
|
1078
1081
|
if(mode==='review')this.#bus.emit(PLAYBACK_RECORD_EVENT,record);
|
|
@@ -1119,7 +1122,7 @@ function eventAuthorityError(code,cause,ErrorType=Error){
|
|
|
1119
1122
|
}
|
|
1120
1123
|
|
|
1121
1124
|
function eventName(value,code='ARCANE_EVENT_SUBSCRIPTION_TYPE_INVALID'){
|
|
1122
|
-
if(
|
|
1125
|
+
if(!is.string(value)
|
|
1123
1126
|
||value.trim()!==value
|
|
1124
1127
|
||value.length<1
|
|
1125
1128
|
||!ARCANE_EVENT_NAME_PATTERN.test(value)){
|
|
@@ -1130,7 +1133,7 @@ function eventName(value,code='ARCANE_EVENT_SUBSCRIPTION_TYPE_INVALID'){
|
|
|
1130
1133
|
|
|
1131
1134
|
function eventDataOptions(value,allowed,code){
|
|
1132
1135
|
if(value===undefined)return Object.create(null);
|
|
1133
|
-
if(!value
|
|
1136
|
+
if(!value||!is.object(value)||is.array(value)){
|
|
1134
1137
|
throw eventAuthorityError(code,undefined,TypeError);
|
|
1135
1138
|
}
|
|
1136
1139
|
const prototype=Object.getPrototypeOf(value);
|
|
@@ -1139,7 +1142,7 @@ function eventDataOptions(value,allowed,code){
|
|
|
1139
1142
|
}
|
|
1140
1143
|
const result=Object.create(null);
|
|
1141
1144
|
for(const key of Reflect.ownKeys(value)){
|
|
1142
|
-
if(
|
|
1145
|
+
if(!is.string(key)||!allowed.has(key)){
|
|
1143
1146
|
throw eventAuthorityError(code,undefined,TypeError);
|
|
1144
1147
|
}
|
|
1145
1148
|
const descriptor=Object.getOwnPropertyDescriptor(value,key);
|
|
@@ -1154,10 +1157,10 @@ function eventDataOptions(value,allowed,code){
|
|
|
1154
1157
|
function eventSignal(value){
|
|
1155
1158
|
if(value===undefined||value===null)return null;
|
|
1156
1159
|
if(!value
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1160
|
+
||!is.object(value)
|
|
1161
|
+
||!is.boolean(value.aborted)
|
|
1162
|
+
||!is.function(value.addEventListener)
|
|
1163
|
+
||!is.function(value.removeEventListener)){
|
|
1161
1164
|
throw eventAuthorityError(
|
|
1162
1165
|
'ARCANE_EVENT_SUBSCRIPTION_SIGNAL_INVALID',
|
|
1163
1166
|
undefined,
|
|
@@ -1168,13 +1171,13 @@ function eventSignal(value){
|
|
|
1168
1171
|
}
|
|
1169
1172
|
|
|
1170
1173
|
function eventListener(value){
|
|
1171
|
-
if(
|
|
1174
|
+
if(is.function(value)){
|
|
1172
1175
|
return {
|
|
1173
1176
|
identity:value,
|
|
1174
1177
|
invoke(event,thisArg,...rest){return value.call(thisArg,event,...rest);}
|
|
1175
1178
|
};
|
|
1176
1179
|
}
|
|
1177
|
-
if(value&&
|
|
1180
|
+
if(value&&is.object(value)&&is.function(value.handleEvent)){
|
|
1178
1181
|
return {
|
|
1179
1182
|
identity:value,
|
|
1180
1183
|
invoke(event){return value.handleEvent(event);}
|
|
@@ -1188,13 +1191,13 @@ function eventListener(value){
|
|
|
1188
1191
|
}
|
|
1189
1192
|
|
|
1190
1193
|
function eventTargetListener(value){
|
|
1191
|
-
if(
|
|
1194
|
+
if(is.function(value)){
|
|
1192
1195
|
return {
|
|
1193
1196
|
identity:value,
|
|
1194
1197
|
invoke(event,thisArg,...rest){return value.call(thisArg,event,...rest);}
|
|
1195
1198
|
};
|
|
1196
1199
|
}
|
|
1197
|
-
if(value&&
|
|
1200
|
+
if(value&&is.object(value)&&is.function(value.handleEvent)){
|
|
1198
1201
|
return {
|
|
1199
1202
|
identity:value,
|
|
1200
1203
|
invoke(event){return value.handleEvent(event);}
|
|
@@ -1204,8 +1207,8 @@ function eventTargetListener(value){
|
|
|
1204
1207
|
}
|
|
1205
1208
|
|
|
1206
1209
|
function compatibilityDetail(value){
|
|
1207
|
-
if(value===null||(
|
|
1208
|
-
if(
|
|
1210
|
+
if(value===null||(!is.object(value)&&!is.function(value)))return value;
|
|
1211
|
+
if(is.array(value))return value.slice();
|
|
1209
1212
|
const prototype=Object.getPrototypeOf(value);
|
|
1210
1213
|
if(prototype!==Object.prototype&&prototype!==null)return value;
|
|
1211
1214
|
const copy=prototype===null?Object.create(null):{};
|
|
@@ -1227,7 +1230,7 @@ function compatibilityDetail(value){
|
|
|
1227
1230
|
|
|
1228
1231
|
function eventTargetOptions(value){
|
|
1229
1232
|
if(value===undefined)return {capture:false,once:false,signal:null};
|
|
1230
|
-
if(
|
|
1233
|
+
if(is.boolean(value)){
|
|
1231
1234
|
return {capture:value,once:false,signal:null};
|
|
1232
1235
|
}
|
|
1233
1236
|
const options=eventDataOptions(
|
|
@@ -1236,7 +1239,7 @@ function eventTargetOptions(value){
|
|
|
1236
1239
|
'ARCANE_EVENT_SUBSCRIPTION_OPTIONS_INVALID'
|
|
1237
1240
|
);
|
|
1238
1241
|
for(const key of ['capture','once','passive']){
|
|
1239
|
-
if(options[key]!==undefined
|
|
1242
|
+
if(options[key]!==undefined&&!is.boolean(options[key])){
|
|
1240
1243
|
throw eventAuthorityError(
|
|
1241
1244
|
'ARCANE_EVENT_SUBSCRIPTION_OPTIONS_INVALID',
|
|
1242
1245
|
undefined,
|
|
@@ -1257,7 +1260,7 @@ function subscriptionOptions(value){
|
|
|
1257
1260
|
new Set(['once','signal']),
|
|
1258
1261
|
'ARCANE_EVENT_SUBSCRIPTION_OPTIONS_INVALID'
|
|
1259
1262
|
);
|
|
1260
|
-
if(options.once!==undefined
|
|
1263
|
+
if(options.once!==undefined&&!is.boolean(options.once)){
|
|
1261
1264
|
throw eventAuthorityError(
|
|
1262
1265
|
'ARCANE_EVENT_SUBSCRIPTION_OPTIONS_INVALID',
|
|
1263
1266
|
undefined,
|
|
@@ -1282,16 +1285,16 @@ function defineDisposable(unsubscribe){
|
|
|
1282
1285
|
|
|
1283
1286
|
function eventLikeRecord(value){
|
|
1284
1287
|
try{
|
|
1285
|
-
if(!value
|
|
1288
|
+
if(!value||!is.object(value)||is.array(value))throw new TypeError();
|
|
1286
1289
|
const EventConstructor=globalThis.Event;
|
|
1287
|
-
if(
|
|
1290
|
+
if(is.function(EventConstructor)&&value instanceof EventConstructor){
|
|
1288
1291
|
if(!('detail' in value))throw new TypeError();
|
|
1289
1292
|
return {
|
|
1290
1293
|
type:eventName(value.type,'ARCANE_EVENT_DISPATCH_EVENT_INVALID'),
|
|
1291
1294
|
detail:value.detail,
|
|
1292
1295
|
cancelable:value.cancelable===true,
|
|
1293
1296
|
defaultPrevented:value.defaultPrevented===true,
|
|
1294
|
-
preventDefault:
|
|
1297
|
+
preventDefault:is.function(value.preventDefault)
|
|
1295
1298
|
?()=>value.preventDefault()
|
|
1296
1299
|
:null
|
|
1297
1300
|
};
|
|
@@ -1311,7 +1314,7 @@ function eventLikeRecord(value){
|
|
|
1311
1314
|
detail:detailDescriptor?.value,
|
|
1312
1315
|
cancelable:cancelableDescriptor?.value===true,
|
|
1313
1316
|
defaultPrevented:preventedDescriptor?.value===true,
|
|
1314
|
-
preventDefault:
|
|
1317
|
+
preventDefault:is.function(value.preventDefault)
|
|
1315
1318
|
?()=>value.preventDefault()
|
|
1316
1319
|
:null
|
|
1317
1320
|
};
|
|
@@ -1364,7 +1367,7 @@ function createArcaneEventAuthority(){
|
|
|
1364
1367
|
|
|
1365
1368
|
function directListenerFailure(error){
|
|
1366
1369
|
try{
|
|
1367
|
-
if(
|
|
1370
|
+
if(is.function(globalThis.reportError)){
|
|
1368
1371
|
globalThis.reportError(error);
|
|
1369
1372
|
return;
|
|
1370
1373
|
}
|
|
@@ -1379,10 +1382,10 @@ function createArcaneEventAuthority(){
|
|
|
1379
1382
|
|
|
1380
1383
|
function completeEventDetail(compatibility,publicDetail){
|
|
1381
1384
|
if(publicDetail===undefined)return compatibility??{};
|
|
1382
|
-
const compatibilityRecord=compatibility&&
|
|
1383
|
-
&&!
|
|
1384
|
-
const publicRecord=publicDetail&&
|
|
1385
|
-
&&!
|
|
1385
|
+
const compatibilityRecord=compatibility&&is.object(compatibility)
|
|
1386
|
+
&&!is.array(compatibility);
|
|
1387
|
+
const publicRecord=publicDetail&&is.object(publicDetail)
|
|
1388
|
+
&&!is.array(publicDetail);
|
|
1386
1389
|
if(compatibilityRecord&&publicRecord)return {...compatibility,...publicDetail};
|
|
1387
1390
|
return {compatibility,publicDetail};
|
|
1388
1391
|
}
|
|
@@ -1658,8 +1661,8 @@ function createArcaneEventAuthority(){
|
|
|
1658
1661
|
throw eventAuthorityError('ARCANE_EVENT_SOURCE_EVENT_TYPE_UNDECLARED');
|
|
1659
1662
|
}
|
|
1660
1663
|
const detail=compatibilityDetail(admitted.detail);
|
|
1661
|
-
const operationId=detail&&
|
|
1662
|
-
&&
|
|
1664
|
+
const operationId=detail&&is.object(detail)
|
|
1665
|
+
&&is.string(detail.operationId)
|
|
1663
1666
|
&&detail.operationId.trim()===detail.operationId
|
|
1664
1667
|
&&detail.operationId
|
|
1665
1668
|
?detail.operationId
|
|
@@ -1680,7 +1683,7 @@ function createArcaneEventAuthority(){
|
|
|
1680
1683
|
}
|
|
1681
1684
|
|
|
1682
1685
|
function createSource(owner,options){
|
|
1683
|
-
if(!owner||(
|
|
1686
|
+
if(!owner||(!is.object(owner)&&!is.function(owner))){
|
|
1684
1687
|
throw eventAuthorityError('ARCANE_EVENT_SOURCE_INVALID',undefined,TypeError);
|
|
1685
1688
|
}
|
|
1686
1689
|
const admitted=eventDataOptions(
|
|
@@ -1689,7 +1692,7 @@ function createArcaneEventAuthority(){
|
|
|
1689
1692
|
'ARCANE_EVENT_SOURCE_INVALID'
|
|
1690
1693
|
);
|
|
1691
1694
|
const source=eventName(admitted.source,'ARCANE_EVENT_SOURCE_INVALID');
|
|
1692
|
-
if(!
|
|
1695
|
+
if(!is.array(admitted.eventTypes)
|
|
1693
1696
|
||admitted.eventTypes.length<1){
|
|
1694
1697
|
throw eventAuthorityError('ARCANE_EVENT_SOURCE_INVALID',undefined,TypeError);
|
|
1695
1698
|
}
|
|
@@ -1704,7 +1707,7 @@ function createArcaneEventAuthority(){
|
|
|
1704
1707
|
eventTypes.push(normalized);
|
|
1705
1708
|
}
|
|
1706
1709
|
if(admitted.onListenerError!==undefined
|
|
1707
|
-
|
|
1710
|
+
&&!is.function(admitted.onListenerError)){
|
|
1708
1711
|
throw eventAuthorityError('ARCANE_EVENT_SOURCE_INVALID',undefined,TypeError);
|
|
1709
1712
|
}
|
|
1710
1713
|
const existing=sourceByOwner.get(owner);
|
|
@@ -1761,12 +1764,12 @@ function createArcaneEventAuthority(){
|
|
|
1761
1764
|
'ARCANE_EVENT_OCCURRENCE_INVALID'
|
|
1762
1765
|
);
|
|
1763
1766
|
const operationId=normalized.operationId??null;
|
|
1764
|
-
if(operationId!==null&&(
|
|
1767
|
+
if(operationId!==null&&(!is.string(operationId)
|
|
1765
1768
|
||operationId.trim()!==operationId
|
|
1766
1769
|
||operationId.length<1)){
|
|
1767
1770
|
throw eventAuthorityError('ARCANE_EVENT_OCCURRENCE_INVALID',undefined,TypeError);
|
|
1768
1771
|
}
|
|
1769
|
-
if(normalized.cancelable!==undefined
|
|
1772
|
+
if(normalized.cancelable!==undefined&&!is.boolean(normalized.cancelable)){
|
|
1770
1773
|
throw eventAuthorityError('ARCANE_EVENT_OCCURRENCE_INVALID',undefined,TypeError);
|
|
1771
1774
|
}
|
|
1772
1775
|
return dispatchOccurrence({
|
|
@@ -1871,21 +1874,21 @@ function createArcaneEventAuthority(){
|
|
|
1871
1874
|
?occurrence.type
|
|
1872
1875
|
:eventName(admitted.type,'ARCANE_EVENT_DOM_OPTIONS_INVALID');
|
|
1873
1876
|
for(const key of ['bubbles','composed','cancelable']){
|
|
1874
|
-
if(admitted[key]!==undefined
|
|
1877
|
+
if(admitted[key]!==undefined&&!is.boolean(admitted[key])){
|
|
1875
1878
|
throw eventAuthorityError('ARCANE_EVENT_DOM_OPTIONS_INVALID',undefined,TypeError);
|
|
1876
1879
|
}
|
|
1877
1880
|
}
|
|
1878
|
-
if(!target
|
|
1879
|
-
|
|
1881
|
+
if(!target||!is.function(target.dispatchEvent)
|
|
1882
|
+
||!is.function(globalThis.CustomEvent)){
|
|
1880
1883
|
throw eventAuthorityError('ARCANE_EVENT_DOM_TARGET_INVALID',undefined,TypeError);
|
|
1881
1884
|
}
|
|
1882
1885
|
const compatibility=compatibilityByOccurrence.get(occurrence);
|
|
1883
1886
|
let detail;
|
|
1884
|
-
const compatibilityPrototype=compatibility&&
|
|
1887
|
+
const compatibilityPrototype=compatibility&&is.object(compatibility)
|
|
1885
1888
|
?Object.getPrototypeOf(compatibility)
|
|
1886
1889
|
:undefined;
|
|
1887
|
-
if(compatibility&&
|
|
1888
|
-
&&!
|
|
1890
|
+
if(compatibility&&is.object(compatibility)
|
|
1891
|
+
&&!is.array(compatibility)
|
|
1889
1892
|
&&(compatibilityPrototype===Object.prototype||compatibilityPrototype===null)){
|
|
1890
1893
|
detail={};
|
|
1891
1894
|
for(const key of Reflect.ownKeys(compatibility)){
|
|
@@ -1934,7 +1937,7 @@ function createArcaneEventAuthority(){
|
|
|
1934
1937
|
function safeDirectOn(type,handler,once=false){
|
|
1935
1938
|
const admittedType=type==='*'?'*':eventName(type);
|
|
1936
1939
|
const admitted=eventListener(handler);
|
|
1937
|
-
if(
|
|
1940
|
+
if(!is.boolean(once)){
|
|
1938
1941
|
throw eventAuthorityError('ARCANE_EVENT_SUBSCRIPTION_OPTIONS_INVALID',undefined,TypeError);
|
|
1939
1942
|
}
|
|
1940
1943
|
const record={type:admittedType,identity:admitted.identity,wrapper:null};
|
|
@@ -2002,9 +2005,9 @@ function createArcaneEventAuthority(){
|
|
|
2002
2005
|
|
|
2003
2006
|
function usableArcaneEventAuthority(value){
|
|
2004
2007
|
return Boolean(value)
|
|
2005
|
-
&&(
|
|
2008
|
+
&&(is.object(value)||is.function(value))
|
|
2006
2009
|
&&value.protocol===ARCANE_EVENT_AUTHORITY_PROTOCOL
|
|
2007
|
-
&&ARCANE_EVENT_REQUIRED_AUTHORITY_API.every(name=>
|
|
2010
|
+
&&ARCANE_EVENT_REQUIRED_AUTHORITY_API.every(name=>is.function(value[name]));
|
|
2008
2011
|
}
|
|
2009
2012
|
|
|
2010
2013
|
function installArcaneEventAuthority(){
|