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
@@ -7,44 +7,70 @@ class FakeCore{
7
7
  }
8
8
 
9
9
  const brandProbe={};
10
+ const brandFailure=Symbol('strong-type brand failure');
11
+ const noArguments=Object.freeze([]);
12
+ const brandProbeArguments=Object.freeze([brandProbe]);
13
+ const emptyStringArguments=Object.freeze(['']);
14
+ const segmentProbeArguments=Object.freeze([-1]);
15
+ const functionToString=Function.prototype.toString;
16
+ const objectConstructorSource=functionToString.call(Object);
17
+ const objectGetPrototypeOf=Object.getPrototypeOf;
18
+ const reflectApply=Reflect.apply;
19
+
20
+ const getterFor=function(prototype,property){
21
+ if(!prototype){
22
+ return false;
23
+ }
10
24
 
11
- const tryBrand=function(check){
12
25
  try{
13
- check();
14
- return true;
26
+ const descriptor=Object.getOwnPropertyDescriptor(prototype,property);
27
+ return descriptor && typeof descriptor.get === 'function' ? descriptor.get : false;
15
28
  }catch(err){
16
29
  return false;
17
30
  }
18
31
  };
19
32
 
20
- const methodBrand=function(value,prototype,method,args=[]){
21
- if(!prototype || typeof prototype[method] !== 'function'){
33
+ const applyBrand=function(value,check,args=noArguments){
34
+ if(typeof check !== 'function'){
22
35
  return false;
23
36
  }
24
37
 
25
- return tryBrand(()=>Reflect.apply(prototype[method],value,args));
38
+ try{
39
+ reflectApply(check,value,args);
40
+ return true;
41
+ }catch(err){
42
+ return false;
43
+ }
26
44
  };
27
45
 
28
- const getterBrand=function(value,prototype,property){
46
+ const applyValue=function(value,check,args=noArguments){
47
+ if(typeof check !== 'function'){
48
+ return brandFailure;
49
+ }
50
+
51
+ try{
52
+ return reflectApply(check,value,args);
53
+ }catch(err){
54
+ return brandFailure;
55
+ }
56
+ };
57
+
58
+ const methodBrand=function(value,prototype,method,args=noArguments){
29
59
  if(!prototype){
30
60
  return false;
31
61
  }
32
62
 
33
- const descriptor=Object.getOwnPropertyDescriptor(prototype,property);
34
- if(!descriptor || typeof descriptor.get !== 'function'){
63
+ let check;
64
+ try{
65
+ check=prototype[method];
66
+ }catch(err){
35
67
  return false;
36
68
  }
37
-
38
- return tryBrand(()=>Reflect.apply(descriptor.get,value,[]));
69
+ return applyBrand(value,check,args);
39
70
  };
40
71
 
41
- const getterValue=function(value,prototype,property){
42
- const descriptor=prototype && Object.getOwnPropertyDescriptor(prototype,property);
43
- if(!descriptor || typeof descriptor.get !== 'function'){
44
- return undefined;
45
- }
46
-
47
- return Reflect.apply(descriptor.get,value,[]);
72
+ const getterBrand=function(value,prototype,property){
73
+ return applyBrand(value,getterFor(prototype,property));
48
74
  };
49
75
 
50
76
  const instanceOf=function(value,constructor){
@@ -67,17 +93,36 @@ const stringTagCheck=function(value,type){
67
93
  }
68
94
  };
69
95
 
96
+ const arrayBufferByteLengthGetter=getterFor(globalThis.ArrayBuffer && globalThis.ArrayBuffer.prototype,'byteLength');
97
+ const arrayBufferResizableGetter=getterFor(globalThis.ArrayBuffer && globalThis.ArrayBuffer.prototype,'resizable');
98
+ const sharedArrayBufferByteLengthGetter=getterFor(globalThis.SharedArrayBuffer && globalThis.SharedArrayBuffer.prototype,'byteLength');
99
+ const sharedArrayBufferGrowableGetter=getterFor(globalThis.SharedArrayBuffer && globalThis.SharedArrayBuffer.prototype,'growable');
100
+ const dataViewByteLengthGetter=getterFor(globalThis.DataView && globalThis.DataView.prototype,'byteLength');
101
+ const regExpSourceGetter=getterFor(globalThis.RegExp && globalThis.RegExp.prototype,'source');
102
+ const intlDateTimeFormatGetter=getterFor(globalThis.Intl && globalThis.Intl.DateTimeFormat && globalThis.Intl.DateTimeFormat.prototype,'format');
103
+ const intlCollatorCompareGetter=getterFor(globalThis.Intl && globalThis.Intl.Collator && globalThis.Intl.Collator.prototype,'compare');
104
+ const intlNumberFormatGetter=getterFor(globalThis.Intl && globalThis.Intl.NumberFormat && globalThis.Intl.NumberFormat.prototype,'format');
105
+ const dateGetTime=Date.prototype.getTime;
106
+ const mapHas=Map.prototype.has;
107
+ const weakMapHas=WeakMap.prototype.has;
108
+ const setHas=Set.prototype.has;
109
+ const weakSetHas=WeakSet.prototype.has;
110
+ const booleanValueOf=Boolean.prototype.valueOf;
111
+ const numberValueOf=Number.prototype.valueOf;
112
+ const bigIntValueOf=globalThis.BigInt && globalThis.BigInt.prototype.valueOf;
113
+ const stringValueOf=String.prototype.valueOf;
114
+ const symbolValueOf=globalThis.Symbol && globalThis.Symbol.prototype.valueOf;
115
+
70
116
  const arrayBufferCheck=function(value){
71
- return getterBrand(value,globalThis.ArrayBuffer && globalThis.ArrayBuffer.prototype,'byteLength');
117
+ return applyBrand(value,arrayBufferByteLengthGetter);
72
118
  };
73
119
 
74
120
  const sharedArrayBufferCheck=function(value){
75
- const constructor=globalThis.SharedArrayBuffer;
76
- return getterBrand(value,constructor && constructor.prototype,'byteLength');
121
+ return applyBrand(value,sharedArrayBufferByteLengthGetter);
77
122
  };
78
123
 
79
124
  const dataViewCheck=function(value){
80
- return getterBrand(value,globalThis.DataView && globalThis.DataView.prototype,'byteLength');
125
+ return applyBrand(value,dataViewByteLengthGetter);
81
126
  };
82
127
 
83
128
  const arrayBufferViewCheck=function(value){
@@ -95,69 +140,61 @@ const typedArrayTagGetter=(function(){
95
140
  })();
96
141
 
97
142
  const typedArrayName=function(value){
98
- if(!arrayBufferViewCheck(value) || dataViewCheck(value) || typeof typedArrayTagGetter !== 'function'){
143
+ if(!arrayBufferViewCheck(value) || typeof typedArrayTagGetter !== 'function'){
99
144
  return false;
100
145
  }
101
146
 
102
- try{
103
- return Reflect.apply(typedArrayTagGetter,value,[]);
104
- }catch(err){
105
- return false;
106
- }
147
+ const name=applyValue(value,typedArrayTagGetter);
148
+ return name === brandFailure ? false : name;
107
149
  };
108
150
 
109
151
  const dateCheck=function(value){
110
- return methodBrand(value,Date.prototype,'getTime');
152
+ return applyBrand(value,dateGetTime);
111
153
  };
112
154
 
113
155
  const validDateCheck=function(value){
114
- if(!dateCheck(value)){
115
- return false;
116
- }
117
-
118
- return !Number.isNaN(Reflect.apply(Date.prototype.getTime,value,[]));
156
+ const time=applyValue(value,dateGetTime);
157
+ return time !== brandFailure && !Number.isNaN(time);
119
158
  };
120
159
 
121
160
  const mapCheck=function(value){
122
- return methodBrand(value,Map.prototype,'has',[brandProbe]);
161
+ return applyBrand(value,mapHas,brandProbeArguments);
123
162
  };
124
163
 
125
164
  const weakMapCheck=function(value){
126
- return methodBrand(value,WeakMap.prototype,'has',[brandProbe]);
165
+ return applyBrand(value,weakMapHas,brandProbeArguments);
127
166
  };
128
167
 
129
168
  const setCheck=function(value){
130
- return methodBrand(value,Set.prototype,'has',[brandProbe]);
169
+ return applyBrand(value,setHas,brandProbeArguments);
131
170
  };
132
171
 
133
172
  const weakSetCheck=function(value){
134
- return methodBrand(value,WeakSet.prototype,'has',[brandProbe]);
173
+ return applyBrand(value,weakSetHas,brandProbeArguments);
135
174
  };
136
175
 
137
176
  const regExpCheck=function(value){
138
- return getterBrand(value,RegExp.prototype,'source');
177
+ return applyBrand(value,regExpSourceGetter);
139
178
  };
140
179
 
141
180
  const boxedBooleanCheck=function(value){
142
- return typeof value === 'object' && value !== null && methodBrand(value,Boolean.prototype,'valueOf');
181
+ return typeof value === 'object' && value !== null && applyBrand(value,booleanValueOf);
143
182
  };
144
183
 
145
184
  const boxedNumberCheck=function(value){
146
- return typeof value === 'object' && value !== null && methodBrand(value,Number.prototype,'valueOf');
185
+ return typeof value === 'object' && value !== null && applyBrand(value,numberValueOf);
147
186
  };
148
187
 
149
188
  const boxedBigIntCheck=function(value){
150
- const prototype=globalThis.BigInt && globalThis.BigInt.prototype;
151
- return typeof value === 'object' && value !== null && methodBrand(value,prototype,'valueOf');
189
+ return typeof value === 'object' && value !== null && applyBrand(value,bigIntValueOf);
152
190
  };
153
191
 
154
192
  const boxedStringCheck=function(value){
155
- return typeof value === 'object' && value !== null && methodBrand(value,String.prototype,'valueOf');
193
+ return typeof value === 'object' && value !== null && applyBrand(value,stringValueOf);
156
194
  };
157
195
 
158
196
  const boxedSymbolCheck=function(value){
159
- const prototype=globalThis.Symbol && globalThis.Symbol.prototype;
160
- return typeof value === 'object' && value !== null && methodBrand(value,prototype,'valueOf');
197
+ return typeof value === 'object' && value !== null && applyBrand(value,symbolValueOf);
161
198
  };
162
199
 
163
200
  const plainObjectCheck=function(value){
@@ -180,7 +217,7 @@ const plainObjectCheck=function(value){
180
217
  }
181
218
 
182
219
  const constructor=prototype.constructor;
183
- return typeof constructor === 'function' && Function.prototype.toString.call(constructor) === Function.prototype.toString.call(Object);
220
+ return typeof constructor === 'function' && functionToString.call(constructor) === objectConstructorSource;
184
221
  };
185
222
 
186
223
  const protocolCheck=function(value,symbol,method){
@@ -215,6 +252,82 @@ const blockedUnionMethods=new Set([
215
252
  'union'
216
253
  ]);
217
254
 
255
+ const unionNamesCache=new Map;
256
+ const unionNamesCacheLimit=128;
257
+
258
+ const normalizeUnionNames=function(types){
259
+ if(typeof types === 'string' && unionNamesCache.has(types)){
260
+ return unionNamesCache.get(types);
261
+ }
262
+
263
+ const source=Array.isArray(types) ? types : typeof types === 'string' ? types.split('|') : [];
264
+ const names=[];
265
+ const length=source.length;
266
+ for(let index=0;index<length;index++){
267
+ const type=source[index];
268
+ if(typeof type !== 'string'){
269
+ continue;
270
+ }
271
+ const name=type.trim();
272
+ if(name){
273
+ names.push(name);
274
+ }
275
+ }
276
+
277
+ if(typeof types === 'string'){
278
+ if(unionNamesCache.size >= unionNamesCacheLimit){
279
+ unionNamesCache.delete(unionNamesCache.keys().next().value);
280
+ }
281
+ Object.freeze(names);
282
+ unionNamesCache.set(types,names);
283
+ }
284
+ return names;
285
+ };
286
+
287
+ let cachedSegmenterConstructor;
288
+ let cachedSegmentMethod;
289
+ let cachedSegmentsPrototype;
290
+ let cachedSegmentsContaining;
291
+ const segmentsContainingFor=function(constructor){
292
+ if(typeof constructor !== 'function'){
293
+ return false;
294
+ }
295
+
296
+ let segment;
297
+ try{
298
+ segment=constructor.prototype && constructor.prototype.segment;
299
+ }catch(err){
300
+ return false;
301
+ }
302
+ if(typeof segment !== 'function'){
303
+ return false;
304
+ }
305
+ if(constructor === cachedSegmenterConstructor && segment === cachedSegmentMethod && typeof cachedSegmentsContaining === 'function'){
306
+ try{
307
+ if(cachedSegmentsPrototype && cachedSegmentsPrototype.containing === cachedSegmentsContaining){
308
+ return cachedSegmentsContaining;
309
+ }
310
+ }catch(err){
311
+ return false;
312
+ }
313
+ }
314
+
315
+ try{
316
+ const prototype=objectGetPrototypeOf(reflectApply(segment,new constructor,emptyStringArguments));
317
+ const containing=prototype && prototype.containing;
318
+ if(typeof containing === 'function'){
319
+ cachedSegmenterConstructor=constructor;
320
+ cachedSegmentMethod=segment;
321
+ cachedSegmentsPrototype=prototype;
322
+ cachedSegmentsContaining=containing;
323
+ return containing;
324
+ }
325
+ }catch(err){
326
+ return false;
327
+ }
328
+ return false;
329
+ };
330
+
218
331
  const validatorFor=function(target,name){
219
332
  if(blockedUnionMethods.has(name)){
220
333
  return false;
@@ -239,11 +352,12 @@ class Is{
239
352
 
240
353
  //core
241
354
  throw(valueType,expectedType){
242
- const err=new TypeError;
243
- err.message=`expected type of ${valueType} to be ${expectedType}`;
244
355
  if(!this.strict){
245
356
  return false;
246
357
  }
358
+
359
+ const err=new TypeError;
360
+ err.message=`expected type of ${valueType} to be ${expectedType}`;
247
361
  throw err;
248
362
  }
249
363
 
@@ -268,8 +382,13 @@ class Is{
268
382
  return this.check(value,stringTagCheck(value,type),`[object ${type}]`);
269
383
  }
270
384
 
271
- compare(value,targetValue,typeName=String(targetValue)){
272
- return this.check(value,Object.is(value,targetValue),typeName);
385
+ compare(value,targetValue,typeName){
386
+ if(Object.is(value,targetValue)){
387
+ return this.check(value,true,typeName);
388
+ }
389
+
390
+ const expectedType=typeName === undefined ? String(targetValue) : typeName;
391
+ return this.check(value,false,expectedType);
273
392
  }
274
393
 
275
394
  globalInstanceCheck(value,type){
@@ -304,16 +423,18 @@ class Is{
304
423
  }
305
424
 
306
425
  union(value,typesString){
307
- const types=Array.isArray(typesString) ? typesString : typeof typesString === 'string' ? typesString.split('|') : [];
308
- const names=types.map(type=>typeof type === 'string' ? type.trim() : '').filter(Boolean);
426
+ const names=normalizeUnionNames(typesString);
309
427
  if(!names.length){
310
428
  return this.throw(typeof typesString,'a pipe-delimited string or array of strong-type methods');
311
429
  }
312
430
 
313
- const validators=names.map(name=>validatorFor(this,name));
314
- if(validators.some(validator=>!validator)){
315
- const invalid=names[validators.findIndex(validator=>!validator)];
316
- return this.throw(invalid,'a method available on strong-type');
431
+ const validators=new Array(names.length);
432
+ for(let index=0;index<names.length;index++){
433
+ const validator=validatorFor(this,names[index]);
434
+ if(!validator){
435
+ return this.throw(names[index],'a method available on strong-type');
436
+ }
437
+ validators[index]=validator;
317
438
  }
318
439
 
319
440
  const weakIs=Object.create(this);
@@ -328,7 +449,11 @@ class Is{
328
449
  }
329
450
  }
330
451
 
331
- return this.throw(typeof value,names.join('|'));
452
+ const fail=this.throw;
453
+ if(fail === defaultThrow && !this.strict){
454
+ return false;
455
+ }
456
+ return reflectApply(fail,this,[typeof value,names.join('|')]);
332
457
  }
333
458
 
334
459
  //values and primitives
@@ -450,11 +575,13 @@ class Is{
450
575
 
451
576
  //objects and collections
452
577
  array(value){
453
- return this.check(value,tryBrand(()=>{
454
- if(!Array.isArray(value)){
455
- throw new TypeError;
456
- }
457
- }),'Array');
578
+ let pass=false;
579
+ try{
580
+ pass=Array.isArray(value);
581
+ }catch(err){
582
+ pass=false;
583
+ }
584
+ return this.check(value,pass,'Array');
458
585
  }
459
586
 
460
587
  date(value){
@@ -486,11 +613,14 @@ class Is{
486
613
  }
487
614
 
488
615
  nullPrototypeObject(value){
489
- const pass=value !== null && typeof value === 'object' && tryBrand(()=>{
490
- if(Object.getPrototypeOf(value) !== null){
491
- throw new TypeError;
616
+ let pass=false;
617
+ if(value !== null && typeof value === 'object'){
618
+ try{
619
+ pass=Object.getPrototypeOf(value) === null;
620
+ }catch(err){
621
+ pass=false;
492
622
  }
493
- });
623
+ }
494
624
  return this.check(value,pass,'null-prototype object');
495
625
  }
496
626
 
@@ -713,15 +843,12 @@ class Is{
713
843
  }
714
844
 
715
845
  resizableArrayBuffer(value){
716
- const prototype=globalThis.ArrayBuffer && globalThis.ArrayBuffer.prototype;
717
- const pass=arrayBufferCheck(value) && getterBrand(value,prototype,'resizable') && getterValue(value,prototype,'resizable') === true;
846
+ const pass=applyValue(value,arrayBufferResizableGetter) === true;
718
847
  return this.check(value,pass,'resizable ArrayBuffer');
719
848
  }
720
849
 
721
850
  growableSharedArrayBuffer(value){
722
- const constructor=globalThis.SharedArrayBuffer;
723
- const prototype=constructor && constructor.prototype;
724
- const pass=sharedArrayBufferCheck(value) && getterBrand(value,prototype,'growable') && getterValue(value,prototype,'growable') === true;
851
+ const pass=applyValue(value,sharedArrayBufferGrowableGetter) === true;
725
852
  return this.check(value,pass,'growable SharedArrayBuffer');
726
853
  }
727
854
 
@@ -733,7 +860,7 @@ class Is{
733
860
  const prototype=globalThis.ArrayBuffer.prototype;
734
861
  const descriptor=Object.getOwnPropertyDescriptor(prototype,'detached');
735
862
  if(descriptor && typeof descriptor.get === 'function'){
736
- return this.check(value,Reflect.apply(descriptor.get,value,[]) === true,'detached ArrayBuffer');
863
+ return this.check(value,reflectApply(descriptor.get,value,noArguments) === true,'detached ArrayBuffer');
737
864
  }
738
865
 
739
866
  let detached=false;
@@ -748,13 +875,13 @@ class Is{
748
875
  //Intl
749
876
  intlDateTimeFormat(value){
750
877
  const constructor=globalThis.Intl && globalThis.Intl.DateTimeFormat;
751
- const pass=constructor && methodBrand(value,constructor.prototype,'resolvedOptions');
878
+ const pass=constructor && applyBrand(value,intlDateTimeFormatGetter);
752
879
  return this.check(value,pass,'Intl.DateTimeFormat');
753
880
  }
754
881
 
755
882
  intlCollator(value){
756
883
  const constructor=globalThis.Intl && globalThis.Intl.Collator;
757
- const pass=constructor && methodBrand(value,constructor.prototype,'resolvedOptions');
884
+ const pass=constructor && applyBrand(value,intlCollatorCompareGetter);
758
885
  return this.check(value,pass,'Intl.Collator');
759
886
  }
760
887
 
@@ -778,7 +905,7 @@ class Is{
778
905
 
779
906
  intlNumberFormat(value){
780
907
  const constructor=globalThis.Intl && globalThis.Intl.NumberFormat;
781
- const pass=constructor && methodBrand(value,constructor.prototype,'resolvedOptions');
908
+ const pass=constructor && applyBrand(value,intlNumberFormatGetter);
782
909
  return this.check(value,pass,'Intl.NumberFormat');
783
910
  }
784
911
 
@@ -802,11 +929,7 @@ class Is{
802
929
 
803
930
  intlSegments(value){
804
931
  const constructor=globalThis.Intl && globalThis.Intl.Segmenter;
805
- let pass=false;
806
- if(constructor){
807
- const prototype=Object.getPrototypeOf(new constructor().segment(''));
808
- pass=methodBrand(value,prototype,'containing',[0]);
809
- }
932
+ const pass=applyBrand(value,segmentsContainingFor(constructor),segmentProbeArguments);
810
933
  return this.check(value,pass,'Intl Segments');
811
934
  }
812
935
 
@@ -819,7 +942,7 @@ class Is{
819
942
  //garbage collection and resource management
820
943
  finalizationRegistry(value){
821
944
  const constructor=globalThis.FinalizationRegistry;
822
- const pass=constructor && methodBrand(value,constructor.prototype,'unregister',[brandProbe]);
945
+ const pass=constructor && methodBrand(value,constructor.prototype,'unregister',brandProbeArguments);
823
946
  return this.check(value,pass,'FinalizationRegistry');
824
947
  }
825
948
 
@@ -1148,4 +1271,6 @@ class Is{
1148
1271
  }
1149
1272
  }
1150
1273
 
1274
+ const defaultThrow=Is.prototype.throw;
1275
+
1151
1276
  export {Is as default,Is};
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strong-type",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "type": "module",
5
5
  "description": "Dependency-free native ESM type enforcement for JavaScript values, objects, classes, browsers, and Node.",
6
6
  "main": "index.js",
@@ -14,6 +14,7 @@
14
14
  "files": [
15
15
  "index.js",
16
16
  "node.js",
17
+ "benchmark/core.js",
17
18
  "assets/strong-type-header.png",
18
19
  "README.md",
19
20
  "licence"
@@ -26,11 +27,16 @@
26
27
  "node": ">=12.21.0"
27
28
  },
28
29
  "scripts": {
30
+ "benchmark": "node benchmark/core.js",
31
+ "benchmark:baseline": "node benchmark/core.js --baseline",
32
+ "benchmark:historical": "node benchmark/core.js --historical",
29
33
  "test": "node scripts/test.js",
30
- "test:core": "node scripts/test.js core",
31
- "test:node": "node scripts/test.js node",
32
- "test:docs": "node scripts/test.js docs",
33
- "coverage": "node --test --experimental-test-coverage --test-coverage-include=index.js --test-coverage-include=node.js --test-coverage-lines=95 --test-coverage-branches=90 --test-coverage-functions=95 test/CI.js test/node.js test/docs.js",
34
+ "test:unit": "node scripts/test.js unit",
35
+ "test:functional": "node scripts/test.js functional",
36
+ "test:integration": "node scripts/test.js integration",
37
+ "test:regression": "node scripts/test.js regression",
38
+ "test:legacy": "node scripts/test.js legacy",
39
+ "coverage": "vanilla-test coverage node",
34
40
  "start": "node scripts/serve.js",
35
41
  "nodeExample": "node ./example/node/typecheck.js",
36
42
  "check": "npm test"
@@ -56,5 +62,8 @@
56
62
  "bugs": {
57
63
  "url": "https://github.com/RIAEvangelist/strong-type/issues"
58
64
  },
59
- "homepage": "https://riaevangelist.github.io/strong-type/"
65
+ "homepage": "https://riaevangelist.github.io/strong-type/",
66
+ "devDependencies": {
67
+ "vanilla-test": "2.1.0"
68
+ }
60
69
  }