@harperfast/harper 5.3.0-beta.1 → 5.3.0-beta.2
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/components/DESIGN.md +421 -0
- package/components/mcp/DESIGN.md +109 -0
- package/components/mcp/audit.ts +21 -17
- package/config/DESIGN.md +306 -0
- package/dataLayer/DESIGN.md +179 -0
- package/dataLayer/restoreMarker.ts +92 -25
- package/dist/components/mcp/audit.d.ts +2 -1
- package/dist/components/mcp/audit.js +21 -17
- package/dist/components/mcp/audit.js.map +1 -1
- package/dist/dataLayer/restoreMarker.d.ts +21 -8
- package/dist/dataLayer/restoreMarker.js +94 -27
- package/dist/dataLayer/restoreMarker.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/resources/RecordEncoder.js +25 -5
- package/dist/resources/RecordEncoder.js.map +1 -1
- package/dist/resources/Table.js +48 -2
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/analytics/write.d.ts +3 -0
- package/dist/resources/analytics/write.js +39 -13
- package/dist/resources/analytics/write.js.map +1 -1
- package/dist/resources/crdt.d.ts +10 -0
- package/dist/resources/crdt.js +22 -0
- package/dist/resources/crdt.js.map +1 -1
- package/dist/resources/databases.js +1 -1
- package/dist/resources/databases.js.map +1 -1
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +2 -2
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +43 -24
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
- package/dist/resources/indexes/fullTextDerivedIndex.d.ts +81 -0
- package/dist/resources/indexes/fullTextDerivedIndex.js +1004 -0
- package/dist/resources/indexes/fullTextDerivedIndex.js.map +1 -0
- package/dist/resources/indexes/fullTextNativeBinding.d.ts +78 -0
- package/dist/resources/indexes/fullTextNativeBinding.js +85 -0
- package/dist/resources/indexes/fullTextNativeBinding.js.map +1 -0
- package/dist/resources/indexes/nativeFullTextDerivedIndexLifecycle.d.ts +24 -0
- package/dist/resources/indexes/nativeFullTextDerivedIndexLifecycle.js +149 -0
- package/dist/resources/indexes/nativeFullTextDerivedIndexLifecycle.js.map +1 -0
- package/dist/resources/recordLockCoordinator.d.ts +5 -5
- package/dist/resources/recordLockCoordinator.js +48 -16
- package/dist/resources/recordLockCoordinator.js.map +1 -1
- package/dist/resources/transactionBroadcast.js +4 -6
- package/dist/resources/transactionBroadcast.js.map +1 -1
- package/dist/security/auth.js +59 -23
- package/dist/security/auth.js.map +1 -1
- package/dist/security/deferredAuthentication.d.ts +11 -0
- package/dist/security/deferredAuthentication.js +25 -3
- package/dist/security/deferredAuthentication.js.map +1 -1
- package/dist/security/jsLoader.js +3 -0
- package/dist/security/jsLoader.js.map +1 -1
- package/dist/server/REST.js +6 -3
- package/dist/server/REST.js.map +1 -1
- package/dist/server/mqtt.js +5 -1
- package/dist/server/mqtt.js.map +1 -1
- package/dist/server/serverHelpers/serverUtilities.d.ts +3 -3
- package/dist/server/serverHelpers/serverUtilities.js +14 -3
- package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
- package/dist/server/serverHelpers/uwsServer.js +4 -1
- package/dist/server/serverHelpers/uwsServer.js.map +1 -1
- package/dist/server/serverHelpers/webSocketCloseReason.d.ts +2 -0
- package/dist/server/serverHelpers/webSocketCloseReason.js +29 -0
- package/dist/server/serverHelpers/webSocketCloseReason.js.map +1 -0
- package/dist/utility/logging/harper_logger.js +1 -0
- package/dist/utility/logging/harper_logger.js.map +1 -1
- package/index.ts +3 -0
- package/npm-shrinkwrap.json +104 -104
- package/package.json +6 -5
- package/resources/DESIGN.md +568 -3
- package/resources/RecordEncoder.ts +27 -5
- package/resources/Table.ts +49 -3
- package/resources/analytics/DESIGN.md +38 -0
- package/resources/analytics/write.ts +40 -14
- package/resources/crdt.ts +22 -0
- package/resources/databases.ts +1 -1
- package/resources/indexes/DESIGN.md +833 -0
- package/resources/indexes/HierarchicalNavigableSmallWorld.ts +44 -25
- package/resources/indexes/fullTextDerivedIndex.ts +1165 -0
- package/resources/indexes/fullTextNativeBinding.ts +146 -0
- package/resources/indexes/nativeFullTextDerivedIndexLifecycle.ts +181 -0
- package/resources/record-locks.md +1407 -0
- package/resources/recordLockCoordinator.ts +61 -22
- package/resources/scheduler/DESIGN.md +40 -0
- package/resources/transactionBroadcast.ts +4 -4
- package/security/DESIGN.md +175 -0
- package/security/auth.ts +53 -24
- package/security/deferredAuthentication.ts +24 -2
- package/security/jsLoader.ts +3 -0
- package/server/DESIGN.md +264 -0
- package/server/REST.ts +6 -3
- package/server/mqtt.ts +6 -4
- package/server/serverHelpers/serverUtilities.ts +14 -3
- package/server/serverHelpers/uwsServer.ts +4 -1
- package/server/serverHelpers/webSocketCloseReason.ts +25 -0
- package/studio/web/assets/{Chat-D3j-1yY1.js → Chat-DADFFGe_.js} +1 -1
- package/studio/web/assets/{FloatingChat-BxJGYcfB.js → FloatingChat-D_mI-rZ7.js} +3 -3
- package/studio/web/assets/{apiToken-CT55oWOe.js → apiToken-c2NiSDHa.js} +1 -1
- package/studio/web/assets/{applications-D9Ct9_vm.js → applications-DktUqh7G.js} +1 -1
- package/studio/web/assets/{cssMode-DV8H7VwA.js → cssMode-Cs_75Xhw.js} +1 -1
- package/studio/web/assets/{editor-uatc0unt.js → editor-19b-Y1IN.js} +1 -1
- package/studio/web/assets/{html-Bm6D6paN.js → html-DiYEQMpB.js} +1 -1
- package/studio/web/assets/{htmlMode-CEn7tpLG.js → htmlMode-CmR0y7P_.js} +1 -1
- package/studio/web/assets/{index-BIXW6Pu4.js → index-Dm0rfkJ7.js} +5 -5
- package/studio/web/assets/{index.lazy-UI7L-Vrk.js → index.lazy-7vqt2CC3.js} +1 -1
- package/studio/web/assets/{javascript-CJ0G3AFZ.js → javascript-BWtCFuOt.js} +1 -1
- package/studio/web/assets/{jsonMode-DQADAYEa.js → jsonMode-Buzzbv9y.js} +1 -1
- package/studio/web/assets/{languageServices-CAQJXWcI.js → languageServices-SqsFWfTM.js} +1 -1
- package/studio/web/assets/{lspLanguageFeatures-CCQ8P5sY.js → lspLanguageFeatures-EMV5cmjo.js} +1 -1
- package/studio/web/assets/{notifications-Cvb3P1lB.js → notifications-CAB-LZWT.js} +1 -1
- package/studio/web/assets/{notifications-BbxTU6Aw.js → notifications-DRzmSRxM.js} +1 -1
- package/studio/web/assets/{profile-Yyb7gsvL.js → profile-BNKAl79n.js} +1 -1
- package/studio/web/assets/{regions-OgjGHlU5.js → regions-CUow_Zw2.js} +1 -1
- package/studio/web/assets/{register-6qwNEOY3.js → register-Dkt3WUMp.js} +2 -2
- package/studio/web/assets/{setComponentFile-BilDMtgB.js → setComponentFile-BZRfMD0N.js} +1 -1
- package/studio/web/assets/{setup-J6qJ7OIU.js → setup-D_yiEPO2.js} +2 -2
- package/studio/web/assets/{status-0RWGcfyD.js → status-DhHh1Ge-.js} +1 -1
- package/studio/web/assets/{toggleHighContrast-BIn-vErT.js → toggleHighContrast-D7L1PDtV.js} +1 -1
- package/studio/web/assets/{tsMode-DgUXku4d.js → tsMode-CCwLk1YS.js} +1 -1
- package/studio/web/assets/{typescript-C9orXcsM.js → typescript-BP1j1mjn.js} +1 -1
- package/studio/web/assets/{useEntityRestURL-BEoXXbUB.js → useEntityRestURL-D7bnYxLw.js} +1 -1
- package/studio/web/assets/{workers-JVzSDmgx.js → workers-tOuCNT17.js} +1 -1
- package/studio/web/assets/{xml-Cq-S8S4X.js → xml-BSG_3mQT.js} +1 -1
- package/studio/web/assets/{yaml-sfoRdh1M.js → yaml-DxiLprBB.js} +1 -1
- package/studio/web/index.html +1 -1
- package/utility/DESIGN.md +55 -0
- package/utility/logging/harper_logger.ts +1 -0
|
@@ -136,12 +136,15 @@ function autoScaleEfConstruction(nodeCount: number): number {
|
|
|
136
136
|
// this only has to be short enough that a table growing from empty picks up a larger ef promptly.
|
|
137
137
|
const NODE_COUNT_TTL = 10_000;
|
|
138
138
|
|
|
139
|
-
// Native traversal-plane geometry (DESIGN.md § Native HNSW plane).
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
|
|
139
|
+
// Native traversal-plane geometry (DESIGN.md § Native HNSW plane). A file-primary index builds no
|
|
140
|
+
// JS graph, so the plane header carries its only layer-0 maximum. maxNodes is a fixed sparse
|
|
141
|
+
// reservation — pages materialize on write — and ids at or past it are rejected by the crate,
|
|
142
|
+
// which disables the plane.
|
|
143
|
+
const PLANE_LAYER0_CAP = 64;
|
|
144
144
|
const PLANE_LAYER0_CAP_MAX = 1024;
|
|
145
|
+
// The crate's fixed connection count, which nativePlane pins the index to: a layer-0 cap below it
|
|
146
|
+
// could not hold a node's own forward edges.
|
|
147
|
+
const PLANE_M = 16;
|
|
145
148
|
const PLANE_MAX_NODES = 1 << 24;
|
|
146
149
|
// Default inline primary-key bytes per plane slot (msgpack-encoded); 40 fits UUIDs inside the slot
|
|
147
150
|
// padding. `nativePlaneKeyCap` raises it for tables whose keys are longer.
|
|
@@ -179,6 +182,14 @@ function nativePlaneMaxNodes(options: any): number {
|
|
|
179
182
|
return maxNodes;
|
|
180
183
|
}
|
|
181
184
|
|
|
185
|
+
function nativePlaneLayer0Cap(options: any): number {
|
|
186
|
+
const layer0Cap = numericOption('nativePlaneLayer0Cap', options?.nativePlaneLayer0Cap) ?? PLANE_LAYER0_CAP;
|
|
187
|
+
if (!Number.isSafeInteger(layer0Cap) || layer0Cap < PLANE_M || layer0Cap > PLANE_LAYER0_CAP_MAX) {
|
|
188
|
+
throw new ClientError(`nativePlaneLayer0Cap must be an integer between ${PLANE_M} and ${PLANE_LAYER0_CAP_MAX}`);
|
|
189
|
+
}
|
|
190
|
+
return layer0Cap;
|
|
191
|
+
}
|
|
192
|
+
|
|
182
193
|
function nativePlaneKeyCap(options: any): number {
|
|
183
194
|
const keyCap = numericOption('nativePlaneKeyCap', options?.nativePlaneKeyCap) ?? PLANE_KEY_CAP;
|
|
184
195
|
if (!Number.isSafeInteger(keyCap) || keyCap < 8 || keyCap > PLANE_KEY_CAP_MAX) {
|
|
@@ -291,6 +302,7 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
291
302
|
'filterExpansion',
|
|
292
303
|
'nativePlaneMaxNodes',
|
|
293
304
|
'nativePlaneKeyCap',
|
|
305
|
+
'nativePlaneLayer0Cap',
|
|
294
306
|
'maxLagMilliseconds',
|
|
295
307
|
]);
|
|
296
308
|
static truthyStructuralOptions = new Set(['nativePlane']);
|
|
@@ -335,6 +347,7 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
335
347
|
}
|
|
336
348
|
if (Object.hasOwn(options, 'nativePlaneMaxNodes')) nativePlaneMaxNodes(options);
|
|
337
349
|
if (Object.hasOwn(options, 'nativePlaneKeyCap')) nativePlaneKeyCap(options);
|
|
350
|
+
if (Object.hasOwn(options, 'nativePlaneLayer0Cap')) nativePlaneLayer0Cap(options);
|
|
338
351
|
}
|
|
339
352
|
static normalizeNativePlaneDeclaration(value: unknown): boolean | undefined {
|
|
340
353
|
if (value === undefined || value === null) return undefined;
|
|
@@ -360,9 +373,9 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
360
373
|
options?.efConstruction === null ||
|
|
361
374
|
options?.mL === null ||
|
|
362
375
|
options?.optimizeRouting === null ||
|
|
363
|
-
(nativeM !== undefined && nativeM !==
|
|
376
|
+
(nativeM !== undefined && nativeM !== PLANE_M) ||
|
|
364
377
|
(nativeEfConstruction !== undefined && nativeEfConstruction !== 200) ||
|
|
365
|
-
(nativeML !== undefined && nativeML !== 1 / Math.log(
|
|
378
|
+
(nativeML !== undefined && nativeML !== 1 / Math.log(PLANE_M)) ||
|
|
366
379
|
(nativeOptimizeRouting !== undefined && nativeOptimizeRouting !== 0.5)
|
|
367
380
|
) {
|
|
368
381
|
throw new ClientError(
|
|
@@ -371,16 +384,18 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
371
384
|
}
|
|
372
385
|
const maxNodes = nativePlaneMaxNodes(options);
|
|
373
386
|
const keyCap = nativePlaneKeyCap(options);
|
|
387
|
+
const layer0Cap = nativePlaneLayer0Cap(options);
|
|
374
388
|
if (options?.quantization === 'none' || options?.distance === 'euclidean' || options?.distance === 'dotProduct') {
|
|
375
389
|
throw new ClientError(
|
|
376
390
|
'nativePlane requires an int8-quantized cosine HNSW index; set nativePlane: false to use the JS index'
|
|
377
391
|
);
|
|
378
392
|
}
|
|
379
|
-
return { nativeM, nativeEfConstruction, nativeML, nativeOptimizeRouting, maxNodes, keyCap };
|
|
393
|
+
return { nativeM, nativeEfConstruction, nativeML, nativeOptimizeRouting, maxNodes, keyCap, layer0Cap };
|
|
380
394
|
}
|
|
381
395
|
static canRunNativePlane(rootStore: unknown, options: any, warnForMissingBinding = true): boolean {
|
|
382
396
|
nativePlaneMaxNodes(options);
|
|
383
397
|
nativePlaneKeyCap(options);
|
|
398
|
+
nativePlaneLayer0Cap(options);
|
|
384
399
|
if (!(rootStore instanceof RocksDatabase) || getPlaneBinding(warnForMissingBinding) == null) return false;
|
|
385
400
|
if (
|
|
386
401
|
options?.M === null ||
|
|
@@ -400,9 +415,9 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
400
415
|
options?.quantization !== 'none' &&
|
|
401
416
|
options?.distance !== 'euclidean' &&
|
|
402
417
|
options?.distance !== 'dotProduct' &&
|
|
403
|
-
(configuredM === undefined || configuredM ===
|
|
418
|
+
(configuredM === undefined || configuredM === PLANE_M) &&
|
|
404
419
|
(configuredEfConstruction === undefined || configuredEfConstruction === 200) &&
|
|
405
|
-
(configuredML === undefined || configuredML === 1 / Math.log(
|
|
420
|
+
(configuredML === undefined || configuredML === 1 / Math.log(PLANE_M)) &&
|
|
406
421
|
(configuredOptimizeRouting === undefined || configuredOptimizeRouting === 0.5);
|
|
407
422
|
if (!baseEligible) return false;
|
|
408
423
|
return true;
|
|
@@ -467,6 +482,7 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
467
482
|
private filePrimary = false;
|
|
468
483
|
private nativePlaneMaxNodes = PLANE_MAX_NODES;
|
|
469
484
|
private nativePlaneKeyCap = PLANE_KEY_CAP;
|
|
485
|
+
private nativePlaneLayer0Cap = PLANE_LAYER0_CAP;
|
|
470
486
|
// Installed by attachDerivedIndexes on every worker: shared readiness of the index and the way
|
|
471
487
|
// to ask its owner for a rebuild. Only the owning worker's runtime ever destroys native state.
|
|
472
488
|
private derivedHost?: DerivedNativeIndexHost;
|
|
@@ -521,7 +537,7 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
521
537
|
if (configuredFilterExpansion !== undefined) this.filterExpansion = configuredFilterExpansion;
|
|
522
538
|
}
|
|
523
539
|
if (options?.nativePlane) {
|
|
524
|
-
const { nativeM, nativeEfConstruction, nativeML, nativeOptimizeRouting, maxNodes, keyCap } =
|
|
540
|
+
const { nativeM, nativeEfConstruction, nativeML, nativeOptimizeRouting, maxNodes, keyCap, layer0Cap } =
|
|
525
541
|
HierarchicalNavigableSmallWorld.validateNativePlaneOptions(indexStore?.rootStore, options);
|
|
526
542
|
if (nativeM !== undefined) this.M = nativeM;
|
|
527
543
|
if (nativeML !== undefined) this.mL = nativeML;
|
|
@@ -529,11 +545,10 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
529
545
|
this.efConstruction = nativeEfConstruction ?? 200;
|
|
530
546
|
this.nativePlaneMaxNodes = maxNodes;
|
|
531
547
|
this.nativePlaneKeyCap = keyCap;
|
|
548
|
+
this.nativePlaneLayer0Cap = layer0Cap;
|
|
532
549
|
// The plane stores int8 bins and computes asymmetric cosine only, so the flag is a
|
|
533
|
-
// no-op for float (quantization: "none") and non-cosine indexes
|
|
534
|
-
|
|
535
|
-
this.planeEligible =
|
|
536
|
-
this.int8 && this.distance === cosineDistance && this.planeLayer0Cap() <= PLANE_LAYER0_CAP_MAX;
|
|
550
|
+
// no-op for float (quantization: "none") and non-cosine indexes.
|
|
551
|
+
this.planeEligible = this.int8 && this.distance === cosineDistance;
|
|
537
552
|
if (!this.planeEligible) {
|
|
538
553
|
throw new ClientError(
|
|
539
554
|
'nativePlane requires an int8-quantized cosine HNSW index; set nativePlane: false to use the JS index'
|
|
@@ -613,10 +628,19 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
613
628
|
// Crash recovery is per-slot inside the crate. The clean flag is advisory;
|
|
614
629
|
// another worker may still be constructing this shared file.
|
|
615
630
|
const opened = Plane.open(filePath);
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
631
|
+
// A header that disagrees with the declaration is a different graph, not a
|
|
632
|
+
// repairable file, and only the owner may destroy it: invalidating through this
|
|
633
|
+
// handle would write a path-based tombstone that could name a replacement the
|
|
634
|
+
// owner had already created.
|
|
635
|
+
const geometryMismatch =
|
|
636
|
+
opened.keyCap !== this.nativePlaneKeyCap
|
|
637
|
+
? `keyCap ${opened.keyCap} differs from the configured ${this.nativePlaneKeyCap}`
|
|
638
|
+
: opened.layer0Cap !== this.nativePlaneLayer0Cap
|
|
639
|
+
? `layer0Cap ${opened.layer0Cap} differs from the configured ${this.nativePlaneLayer0Cap}`
|
|
640
|
+
: undefined;
|
|
641
|
+
if (geometryMismatch) {
|
|
642
|
+
this.disablePlane(new Error(`plane ${geometryMismatch}`));
|
|
643
|
+
return null;
|
|
620
644
|
}
|
|
621
645
|
return (this.plane = opened);
|
|
622
646
|
} catch (openError) {
|
|
@@ -655,7 +679,7 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
655
679
|
return (this.plane = Plane.create(
|
|
656
680
|
filePath,
|
|
657
681
|
dims,
|
|
658
|
-
this.
|
|
682
|
+
this.nativePlaneLayer0Cap,
|
|
659
683
|
this.nativePlaneMaxNodes,
|
|
660
684
|
this.nativePlaneKeyCap
|
|
661
685
|
));
|
|
@@ -689,11 +713,6 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
689
713
|
return this.derivedHost?.readiness().state ?? 'unknown';
|
|
690
714
|
}
|
|
691
715
|
|
|
692
|
-
/** The JS graph's effective layer-0 cap for this configuration; sizes the plane's slots. */
|
|
693
|
-
private planeLayer0Cap(): number {
|
|
694
|
-
return this.optimizeRouting ? this.M << 3 : this.M << 1;
|
|
695
|
-
}
|
|
696
|
-
|
|
697
716
|
/**
|
|
698
717
|
* Detach this process from the plane after a failure and ask the index's owner for a rebuild.
|
|
699
718
|
* Only the owner destroys native state (`resetDerivedStorage` under its epoch), so a failure
|