@rlabs-inc/memory 0.3.2 → 0.3.5
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/dist/index.js +2520 -1404
- package/dist/index.mjs +2513 -1397
- package/dist/server/index.mjs +35910 -2628
- package/hooks/gemini/curation.ts +73 -0
- package/hooks/gemini/session-start.ts +72 -0
- package/hooks/gemini/user-prompt.ts +77 -0
- package/package.json +3 -2
- package/src/cli/commands/install.ts +267 -29
- package/src/cli/index.ts +8 -9
- package/src/cli/commands/install-gemini.ts +0 -146
- /package/hooks/{curation.ts → claude/curation.ts} +0 -0
- /package/hooks/{session-start.ts → claude/session-start.ts} +0 -0
- /package/hooks/{user-prompt.ts → claude/user-prompt.ts} +0 -0
package/dist/index.mjs
CHANGED
|
@@ -212,10 +212,10 @@ var require_lib = __commonJS((exports, module) => {
|
|
|
212
212
|
|
|
213
213
|
// node_modules/whatwg-url/lib/utils.js
|
|
214
214
|
var require_utils = __commonJS((exports, module) => {
|
|
215
|
-
exports.mixin = function mixin(target,
|
|
216
|
-
const keys = Object.getOwnPropertyNames(
|
|
215
|
+
exports.mixin = function mixin(target, source2) {
|
|
216
|
+
const keys = Object.getOwnPropertyNames(source2);
|
|
217
217
|
for (let i = 0;i < keys.length; ++i) {
|
|
218
|
-
Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(
|
|
218
|
+
Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(source2, keys[i]));
|
|
219
219
|
}
|
|
220
220
|
};
|
|
221
221
|
exports.wrapperSymbol = Symbol("wrapper");
|
|
@@ -2535,8 +2535,8 @@ var require_lib2 = __commonJS((exports, module) => {
|
|
|
2535
2535
|
function isRequest(input) {
|
|
2536
2536
|
return typeof input === "object" && typeof input[INTERNALS$2] === "object";
|
|
2537
2537
|
}
|
|
2538
|
-
function isAbortSignal(
|
|
2539
|
-
const proto =
|
|
2538
|
+
function isAbortSignal(signal2) {
|
|
2539
|
+
const proto = signal2 && typeof signal2 === "object" && Object.getPrototypeOf(signal2);
|
|
2540
2540
|
return !!(proto && proto.constructor.name === "AbortSignal");
|
|
2541
2541
|
}
|
|
2542
2542
|
|
|
@@ -2571,10 +2571,10 @@ var require_lib2 = __commonJS((exports, module) => {
|
|
|
2571
2571
|
headers.append("Content-Type", contentType);
|
|
2572
2572
|
}
|
|
2573
2573
|
}
|
|
2574
|
-
let
|
|
2574
|
+
let signal2 = isRequest(input) ? input.signal : null;
|
|
2575
2575
|
if ("signal" in init)
|
|
2576
|
-
|
|
2577
|
-
if (
|
|
2576
|
+
signal2 = init.signal;
|
|
2577
|
+
if (signal2 != null && !isAbortSignal(signal2)) {
|
|
2578
2578
|
throw new TypeError("Expected signal to be an instanceof AbortSignal");
|
|
2579
2579
|
}
|
|
2580
2580
|
this[INTERNALS$2] = {
|
|
@@ -2582,7 +2582,7 @@ var require_lib2 = __commonJS((exports, module) => {
|
|
|
2582
2582
|
redirect: init.redirect || input.redirect || "follow",
|
|
2583
2583
|
headers,
|
|
2584
2584
|
parsedURL,
|
|
2585
|
-
signal
|
|
2585
|
+
signal: signal2
|
|
2586
2586
|
};
|
|
2587
2587
|
this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20;
|
|
2588
2588
|
this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true;
|
|
@@ -2697,7 +2697,7 @@ var require_lib2 = __commonJS((exports, module) => {
|
|
|
2697
2697
|
const request = new Request2(url, opts);
|
|
2698
2698
|
const options = getNodeRequestOptions(request);
|
|
2699
2699
|
const send = (options.protocol === "https:" ? https : http).request;
|
|
2700
|
-
const
|
|
2700
|
+
const signal2 = request.signal;
|
|
2701
2701
|
let response = null;
|
|
2702
2702
|
const abort = function abort() {
|
|
2703
2703
|
let error = new AbortError("The user aborted a request.");
|
|
@@ -2709,7 +2709,7 @@ var require_lib2 = __commonJS((exports, module) => {
|
|
|
2709
2709
|
return;
|
|
2710
2710
|
response.body.emit("error", error);
|
|
2711
2711
|
};
|
|
2712
|
-
if (
|
|
2712
|
+
if (signal2 && signal2.aborted) {
|
|
2713
2713
|
abort();
|
|
2714
2714
|
return;
|
|
2715
2715
|
}
|
|
@@ -2719,13 +2719,13 @@ var require_lib2 = __commonJS((exports, module) => {
|
|
|
2719
2719
|
};
|
|
2720
2720
|
const req = send(options);
|
|
2721
2721
|
let reqTimeout;
|
|
2722
|
-
if (
|
|
2723
|
-
|
|
2722
|
+
if (signal2) {
|
|
2723
|
+
signal2.addEventListener("abort", abortAndFinalize);
|
|
2724
2724
|
}
|
|
2725
2725
|
function finalize() {
|
|
2726
2726
|
req.abort();
|
|
2727
|
-
if (
|
|
2728
|
-
|
|
2727
|
+
if (signal2)
|
|
2728
|
+
signal2.removeEventListener("abort", abortAndFinalize);
|
|
2729
2729
|
clearTimeout(reqTimeout);
|
|
2730
2730
|
}
|
|
2731
2731
|
if (request.timeout) {
|
|
@@ -2744,7 +2744,7 @@ var require_lib2 = __commonJS((exports, module) => {
|
|
|
2744
2744
|
finalize();
|
|
2745
2745
|
});
|
|
2746
2746
|
fixResponseChunkedTransferBadEnding(req, function(err) {
|
|
2747
|
-
if (
|
|
2747
|
+
if (signal2 && signal2.aborted) {
|
|
2748
2748
|
return;
|
|
2749
2749
|
}
|
|
2750
2750
|
if (response && response.body) {
|
|
@@ -2755,7 +2755,7 @@ var require_lib2 = __commonJS((exports, module) => {
|
|
|
2755
2755
|
req.on("socket", function(s) {
|
|
2756
2756
|
s.addListener("close", function(hadError) {
|
|
2757
2757
|
const hasDataListener = s.listenerCount("data") > 0;
|
|
2758
|
-
if (response && hasDataListener && !hadError && !(
|
|
2758
|
+
if (response && hasDataListener && !hadError && !(signal2 && signal2.aborted)) {
|
|
2759
2759
|
const err = new Error("Premature close");
|
|
2760
2760
|
err.code = "ERR_STREAM_PREMATURE_CLOSE";
|
|
2761
2761
|
response.body.emit("error", err);
|
|
@@ -2834,8 +2834,8 @@ var require_lib2 = __commonJS((exports, module) => {
|
|
|
2834
2834
|
}
|
|
2835
2835
|
}
|
|
2836
2836
|
res.once("end", function() {
|
|
2837
|
-
if (
|
|
2838
|
-
|
|
2837
|
+
if (signal2)
|
|
2838
|
+
signal2.removeEventListener("abort", abortAndFinalize);
|
|
2839
2839
|
});
|
|
2840
2840
|
let body = res.pipe(new PassThrough$1);
|
|
2841
2841
|
const response_options = {
|
|
@@ -5005,20 +5005,20 @@ var init_blobHelpers = __esm(() => {
|
|
|
5005
5005
|
});
|
|
5006
5006
|
|
|
5007
5007
|
// node_modules/formdata-node/lib/esm/Blob.js
|
|
5008
|
-
var __classPrivateFieldGet = function(receiver,
|
|
5008
|
+
var __classPrivateFieldGet = function(receiver, state, kind2, f2) {
|
|
5009
5009
|
if (kind2 === "a" && !f2)
|
|
5010
5010
|
throw new TypeError("Private accessor was defined without a getter");
|
|
5011
|
-
if (typeof
|
|
5011
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
5012
5012
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5013
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
5014
|
-
}, __classPrivateFieldSet = function(receiver,
|
|
5013
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
5014
|
+
}, __classPrivateFieldSet = function(receiver, state, value, kind2, f2) {
|
|
5015
5015
|
if (kind2 === "m")
|
|
5016
5016
|
throw new TypeError("Private method is not writable");
|
|
5017
5017
|
if (kind2 === "a" && !f2)
|
|
5018
5018
|
throw new TypeError("Private accessor was defined without a setter");
|
|
5019
|
-
if (typeof
|
|
5019
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
5020
5020
|
throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5021
|
-
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value :
|
|
5021
|
+
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value : state.set(receiver, value), value;
|
|
5022
5022
|
}, _Blob_parts, _Blob_type, _Blob_size, Blob2;
|
|
5023
5023
|
var init_Blob = __esm(() => {
|
|
5024
5024
|
init_ponyfill();
|
|
@@ -5119,20 +5119,20 @@ var init_Blob = __esm(() => {
|
|
|
5119
5119
|
});
|
|
5120
5120
|
|
|
5121
5121
|
// node_modules/formdata-node/lib/esm/File.js
|
|
5122
|
-
var __classPrivateFieldSet2 = function(receiver,
|
|
5122
|
+
var __classPrivateFieldSet2 = function(receiver, state, value, kind2, f2) {
|
|
5123
5123
|
if (kind2 === "m")
|
|
5124
5124
|
throw new TypeError("Private method is not writable");
|
|
5125
5125
|
if (kind2 === "a" && !f2)
|
|
5126
5126
|
throw new TypeError("Private accessor was defined without a setter");
|
|
5127
|
-
if (typeof
|
|
5127
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
5128
5128
|
throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5129
|
-
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value :
|
|
5130
|
-
}, __classPrivateFieldGet2 = function(receiver,
|
|
5129
|
+
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value : state.set(receiver, value), value;
|
|
5130
|
+
}, __classPrivateFieldGet2 = function(receiver, state, kind2, f2) {
|
|
5131
5131
|
if (kind2 === "a" && !f2)
|
|
5132
5132
|
throw new TypeError("Private accessor was defined without a getter");
|
|
5133
|
-
if (typeof
|
|
5133
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
5134
5134
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5135
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
5135
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
5136
5136
|
}, _File_name, _File_lastModified, File2;
|
|
5137
5137
|
var init_File = __esm(() => {
|
|
5138
5138
|
init_Blob();
|
|
@@ -5189,12 +5189,12 @@ var init_deprecateConstructorEntries = __esm(() => {
|
|
|
5189
5189
|
|
|
5190
5190
|
// node_modules/formdata-node/lib/esm/FormData.js
|
|
5191
5191
|
import { inspect } from "util";
|
|
5192
|
-
var __classPrivateFieldGet3 = function(receiver,
|
|
5192
|
+
var __classPrivateFieldGet3 = function(receiver, state, kind2, f2) {
|
|
5193
5193
|
if (kind2 === "a" && !f2)
|
|
5194
5194
|
throw new TypeError("Private accessor was defined without a getter");
|
|
5195
|
-
if (typeof
|
|
5195
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
5196
5196
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5197
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
5197
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
5198
5198
|
}, _FormData_instances, _FormData_entries, _FormData_setEntry, FormData2;
|
|
5199
5199
|
var init_FormData = __esm(() => {
|
|
5200
5200
|
init_File();
|
|
@@ -6258,17 +6258,17 @@ var require_abort_controller = __commonJS((exports, module) => {
|
|
|
6258
6258
|
}
|
|
6259
6259
|
eventTargetShim.defineEventAttribute(AbortSignal.prototype, "abort");
|
|
6260
6260
|
function createAbortSignal() {
|
|
6261
|
-
const
|
|
6262
|
-
eventTargetShim.EventTarget.call(
|
|
6263
|
-
abortedFlags.set(
|
|
6264
|
-
return
|
|
6261
|
+
const signal2 = Object.create(AbortSignal.prototype);
|
|
6262
|
+
eventTargetShim.EventTarget.call(signal2);
|
|
6263
|
+
abortedFlags.set(signal2, false);
|
|
6264
|
+
return signal2;
|
|
6265
6265
|
}
|
|
6266
|
-
function abortSignal(
|
|
6267
|
-
if (abortedFlags.get(
|
|
6266
|
+
function abortSignal(signal2) {
|
|
6267
|
+
if (abortedFlags.get(signal2) !== false) {
|
|
6268
6268
|
return;
|
|
6269
6269
|
}
|
|
6270
|
-
abortedFlags.set(
|
|
6271
|
-
|
|
6270
|
+
abortedFlags.set(signal2, true);
|
|
6271
|
+
signal2.dispatchEvent({ type: "abort" });
|
|
6272
6272
|
}
|
|
6273
6273
|
var abortedFlags = new WeakMap;
|
|
6274
6274
|
Object.defineProperties(AbortSignal.prototype, {
|
|
@@ -6294,11 +6294,11 @@ var require_abort_controller = __commonJS((exports, module) => {
|
|
|
6294
6294
|
}
|
|
6295
6295
|
var signals = new WeakMap;
|
|
6296
6296
|
function getSignal(controller) {
|
|
6297
|
-
const
|
|
6298
|
-
if (
|
|
6297
|
+
const signal2 = signals.get(controller);
|
|
6298
|
+
if (signal2 == null) {
|
|
6299
6299
|
throw new TypeError(`Expected 'this' to be an 'AbortController' object, but got ${controller === null ? "null" : typeof controller}`);
|
|
6300
6300
|
}
|
|
6301
|
-
return
|
|
6301
|
+
return signal2;
|
|
6302
6302
|
}
|
|
6303
6303
|
Object.defineProperties(AbortController2.prototype, {
|
|
6304
6304
|
signal: { enumerable: true },
|
|
@@ -6388,20 +6388,20 @@ var init_isFormData = __esm(() => {
|
|
|
6388
6388
|
});
|
|
6389
6389
|
|
|
6390
6390
|
// node_modules/form-data-encoder/lib/esm/FormDataEncoder.js
|
|
6391
|
-
var __classPrivateFieldSet3 = function(receiver,
|
|
6391
|
+
var __classPrivateFieldSet3 = function(receiver, state, value, kind2, f2) {
|
|
6392
6392
|
if (kind2 === "m")
|
|
6393
6393
|
throw new TypeError("Private method is not writable");
|
|
6394
6394
|
if (kind2 === "a" && !f2)
|
|
6395
6395
|
throw new TypeError("Private accessor was defined without a setter");
|
|
6396
|
-
if (typeof
|
|
6396
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
6397
6397
|
throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6398
|
-
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value :
|
|
6399
|
-
}, __classPrivateFieldGet4 = function(receiver,
|
|
6398
|
+
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value : state.set(receiver, value), value;
|
|
6399
|
+
}, __classPrivateFieldGet4 = function(receiver, state, kind2, f2) {
|
|
6400
6400
|
if (kind2 === "a" && !f2)
|
|
6401
6401
|
throw new TypeError("Private accessor was defined without a getter");
|
|
6402
|
-
if (typeof
|
|
6402
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
6403
6403
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
6404
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
6404
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
6405
6405
|
}, _FormDataEncoder_instances, _FormDataEncoder_CRLF, _FormDataEncoder_CRLF_BYTES, _FormDataEncoder_CRLF_BYTES_LENGTH, _FormDataEncoder_DASHES, _FormDataEncoder_encoder, _FormDataEncoder_footer, _FormDataEncoder_form, _FormDataEncoder_options, _FormDataEncoder_getFieldHeader, defaultOptions, FormDataEncoder;
|
|
6406
6406
|
var init_FormDataEncoder = __esm(() => {
|
|
6407
6407
|
init_createBoundary();
|
|
@@ -6603,20 +6603,20 @@ async function fileFromPath2(path, filenameOrOptions, options) {
|
|
|
6603
6603
|
const stats = await fs.stat(path);
|
|
6604
6604
|
return createFileFromPath(path, stats, filenameOrOptions, options);
|
|
6605
6605
|
}
|
|
6606
|
-
var import_node_domexception, __classPrivateFieldSet4 = function(receiver,
|
|
6606
|
+
var import_node_domexception, __classPrivateFieldSet4 = function(receiver, state, value, kind2, f2) {
|
|
6607
6607
|
if (kind2 === "m")
|
|
6608
6608
|
throw new TypeError("Private method is not writable");
|
|
6609
6609
|
if (kind2 === "a" && !f2)
|
|
6610
6610
|
throw new TypeError("Private accessor was defined without a setter");
|
|
6611
|
-
if (typeof
|
|
6611
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
6612
6612
|
throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6613
|
-
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value :
|
|
6614
|
-
}, __classPrivateFieldGet5 = function(receiver,
|
|
6613
|
+
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value : state.set(receiver, value), value;
|
|
6614
|
+
}, __classPrivateFieldGet5 = function(receiver, state, kind2, f2) {
|
|
6615
6615
|
if (kind2 === "a" && !f2)
|
|
6616
6616
|
throw new TypeError("Private accessor was defined without a getter");
|
|
6617
|
-
if (typeof
|
|
6617
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
6618
6618
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
6619
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
6619
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
6620
6620
|
}, _FileFromPath_path, _FileFromPath_start, MESSAGE, FileFromPath;
|
|
6621
6621
|
var init_fileFromPath = __esm(() => {
|
|
6622
6622
|
import_node_domexception = __toESM(require_node_domexception(), 1);
|
|
@@ -6918,20 +6918,20 @@ function findDoubleNewlineIndex(buffer) {
|
|
|
6918
6918
|
}
|
|
6919
6919
|
return -1;
|
|
6920
6920
|
}
|
|
6921
|
-
var __classPrivateFieldSet5 = function(receiver,
|
|
6921
|
+
var __classPrivateFieldSet5 = function(receiver, state, value, kind2, f2) {
|
|
6922
6922
|
if (kind2 === "m")
|
|
6923
6923
|
throw new TypeError("Private method is not writable");
|
|
6924
6924
|
if (kind2 === "a" && !f2)
|
|
6925
6925
|
throw new TypeError("Private accessor was defined without a setter");
|
|
6926
|
-
if (typeof
|
|
6926
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
6927
6927
|
throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6928
|
-
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value :
|
|
6929
|
-
}, __classPrivateFieldGet6 = function(receiver,
|
|
6928
|
+
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value : state.set(receiver, value), value;
|
|
6929
|
+
}, __classPrivateFieldGet6 = function(receiver, state, kind2, f2) {
|
|
6930
6930
|
if (kind2 === "a" && !f2)
|
|
6931
6931
|
throw new TypeError("Private accessor was defined without a getter");
|
|
6932
|
-
if (typeof
|
|
6932
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
6933
6933
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
6934
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
6934
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
6935
6935
|
}, _LineDecoder_carriageReturnIndex;
|
|
6936
6936
|
var init_line = __esm(() => {
|
|
6937
6937
|
init_error();
|
|
@@ -7512,9 +7512,9 @@ class APIClient {
|
|
|
7512
7512
|
}).join("&");
|
|
7513
7513
|
}
|
|
7514
7514
|
async fetchWithTimeout(url, init, ms, controller) {
|
|
7515
|
-
const { signal, ...options } = init || {};
|
|
7516
|
-
if (
|
|
7517
|
-
|
|
7515
|
+
const { signal: signal2, ...options } = init || {};
|
|
7516
|
+
if (signal2)
|
|
7517
|
+
signal2.addEventListener("abort", () => controller.abort());
|
|
7518
7518
|
const timeout = setTimeout(() => controller.abort(), ms);
|
|
7519
7519
|
const fetchOptions = {
|
|
7520
7520
|
signal: controller.signal,
|
|
@@ -7644,20 +7644,20 @@ function debug(action, ...args) {
|
|
|
7644
7644
|
console.log(`Anthropic:DEBUG:${action}`, ...args);
|
|
7645
7645
|
}
|
|
7646
7646
|
}
|
|
7647
|
-
var __classPrivateFieldSet6 = function(receiver,
|
|
7647
|
+
var __classPrivateFieldSet6 = function(receiver, state, value, kind2, f2) {
|
|
7648
7648
|
if (kind2 === "m")
|
|
7649
7649
|
throw new TypeError("Private method is not writable");
|
|
7650
7650
|
if (kind2 === "a" && !f2)
|
|
7651
7651
|
throw new TypeError("Private accessor was defined without a setter");
|
|
7652
|
-
if (typeof
|
|
7652
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
7653
7653
|
throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
7654
|
-
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value :
|
|
7655
|
-
}, __classPrivateFieldGet7 = function(receiver,
|
|
7654
|
+
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value : state.set(receiver, value), value;
|
|
7655
|
+
}, __classPrivateFieldGet7 = function(receiver, state, kind2, f2) {
|
|
7656
7656
|
if (kind2 === "a" && !f2)
|
|
7657
7657
|
throw new TypeError("Private accessor was defined without a getter");
|
|
7658
|
-
if (typeof
|
|
7658
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
7659
7659
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
7660
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
7660
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
7661
7661
|
}, _AbstractPage_client, APIPromise, AbstractPage, PagePromise, createResponseHeaders = (headers) => {
|
|
7662
7662
|
return new Proxy(Object.fromEntries(headers.entries()), {
|
|
7663
7663
|
get(target, name) {
|
|
@@ -8372,20 +8372,20 @@ var init_parser = () => {};
|
|
|
8372
8372
|
|
|
8373
8373
|
// node_modules/@anthropic-ai/sdk/lib/BetaMessageStream.mjs
|
|
8374
8374
|
function checkNever(x2) {}
|
|
8375
|
-
var __classPrivateFieldSet7 = function(receiver,
|
|
8375
|
+
var __classPrivateFieldSet7 = function(receiver, state, value, kind2, f2) {
|
|
8376
8376
|
if (kind2 === "m")
|
|
8377
8377
|
throw new TypeError("Private method is not writable");
|
|
8378
8378
|
if (kind2 === "a" && !f2)
|
|
8379
8379
|
throw new TypeError("Private accessor was defined without a setter");
|
|
8380
|
-
if (typeof
|
|
8380
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
8381
8381
|
throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
8382
|
-
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value :
|
|
8383
|
-
}, __classPrivateFieldGet8 = function(receiver,
|
|
8382
|
+
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value : state.set(receiver, value), value;
|
|
8383
|
+
}, __classPrivateFieldGet8 = function(receiver, state, kind2, f2) {
|
|
8384
8384
|
if (kind2 === "a" && !f2)
|
|
8385
8385
|
throw new TypeError("Private accessor was defined without a getter");
|
|
8386
|
-
if (typeof
|
|
8386
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
8387
8387
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
8388
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
8388
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
8389
8389
|
}, _BetaMessageStream_instances, _BetaMessageStream_currentMessageSnapshot, _BetaMessageStream_connectedPromise, _BetaMessageStream_resolveConnectedPromise, _BetaMessageStream_rejectConnectedPromise, _BetaMessageStream_endPromise, _BetaMessageStream_resolveEndPromise, _BetaMessageStream_rejectEndPromise, _BetaMessageStream_listeners, _BetaMessageStream_ended, _BetaMessageStream_errored, _BetaMessageStream_aborted, _BetaMessageStream_catchingPromiseCreated, _BetaMessageStream_response, _BetaMessageStream_request_id, _BetaMessageStream_getFinalMessage, _BetaMessageStream_getFinalText, _BetaMessageStream_handleError, _BetaMessageStream_beginRequest, _BetaMessageStream_addStreamEvent, _BetaMessageStream_endRequest, _BetaMessageStream_accumulateMessage, JSON_BUF_PROPERTY = "__json_buf", BetaMessageStream;
|
|
8390
8390
|
var init_BetaMessageStream = __esm(() => {
|
|
8391
8391
|
init_error();
|
|
@@ -8487,11 +8487,11 @@ var init_BetaMessageStream = __esm(() => {
|
|
|
8487
8487
|
}
|
|
8488
8488
|
}
|
|
8489
8489
|
async _createMessage(messages, params, options) {
|
|
8490
|
-
const
|
|
8491
|
-
if (
|
|
8492
|
-
if (
|
|
8490
|
+
const signal2 = options?.signal;
|
|
8491
|
+
if (signal2) {
|
|
8492
|
+
if (signal2.aborted)
|
|
8493
8493
|
this.controller.abort();
|
|
8494
|
-
|
|
8494
|
+
signal2.addEventListener("abort", () => this.controller.abort());
|
|
8495
8495
|
}
|
|
8496
8496
|
__classPrivateFieldGet8(this, _BetaMessageStream_instances, "m", _BetaMessageStream_beginRequest).call(this);
|
|
8497
8497
|
const { response, data: stream } = await messages.create({ ...params, stream: true }, { ...options, signal: this.controller.signal }).withResponse();
|
|
@@ -8605,11 +8605,11 @@ var init_BetaMessageStream = __esm(() => {
|
|
|
8605
8605
|
}
|
|
8606
8606
|
}
|
|
8607
8607
|
async _fromReadableStream(readableStream, options) {
|
|
8608
|
-
const
|
|
8609
|
-
if (
|
|
8610
|
-
if (
|
|
8608
|
+
const signal2 = options?.signal;
|
|
8609
|
+
if (signal2) {
|
|
8610
|
+
if (signal2.aborted)
|
|
8611
8611
|
this.controller.abort();
|
|
8612
|
-
|
|
8612
|
+
signal2.addEventListener("abort", () => this.controller.abort());
|
|
8613
8613
|
}
|
|
8614
8614
|
__classPrivateFieldGet8(this, _BetaMessageStream_instances, "m", _BetaMessageStream_beginRequest).call(this);
|
|
8615
8615
|
this._connected(null);
|
|
@@ -8980,20 +8980,20 @@ var init_batches2 = __esm(() => {
|
|
|
8980
8980
|
|
|
8981
8981
|
// node_modules/@anthropic-ai/sdk/lib/MessageStream.mjs
|
|
8982
8982
|
function checkNever2(x2) {}
|
|
8983
|
-
var __classPrivateFieldSet8 = function(receiver,
|
|
8983
|
+
var __classPrivateFieldSet8 = function(receiver, state, value, kind2, f2) {
|
|
8984
8984
|
if (kind2 === "m")
|
|
8985
8985
|
throw new TypeError("Private method is not writable");
|
|
8986
8986
|
if (kind2 === "a" && !f2)
|
|
8987
8987
|
throw new TypeError("Private accessor was defined without a setter");
|
|
8988
|
-
if (typeof
|
|
8988
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
8989
8989
|
throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
8990
|
-
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value :
|
|
8991
|
-
}, __classPrivateFieldGet9 = function(receiver,
|
|
8990
|
+
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value : state.set(receiver, value), value;
|
|
8991
|
+
}, __classPrivateFieldGet9 = function(receiver, state, kind2, f2) {
|
|
8992
8992
|
if (kind2 === "a" && !f2)
|
|
8993
8993
|
throw new TypeError("Private accessor was defined without a getter");
|
|
8994
|
-
if (typeof
|
|
8994
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
8995
8995
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
8996
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
8996
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
8997
8997
|
}, _MessageStream_instances, _MessageStream_currentMessageSnapshot, _MessageStream_connectedPromise, _MessageStream_resolveConnectedPromise, _MessageStream_rejectConnectedPromise, _MessageStream_endPromise, _MessageStream_resolveEndPromise, _MessageStream_rejectEndPromise, _MessageStream_listeners, _MessageStream_ended, _MessageStream_errored, _MessageStream_aborted, _MessageStream_catchingPromiseCreated, _MessageStream_response, _MessageStream_request_id, _MessageStream_getFinalMessage, _MessageStream_getFinalText, _MessageStream_handleError, _MessageStream_beginRequest, _MessageStream_addStreamEvent, _MessageStream_endRequest, _MessageStream_accumulateMessage, JSON_BUF_PROPERTY2 = "__json_buf", MessageStream;
|
|
8998
8998
|
var init_MessageStream = __esm(() => {
|
|
8999
8999
|
init_error();
|
|
@@ -9095,11 +9095,11 @@ var init_MessageStream = __esm(() => {
|
|
|
9095
9095
|
}
|
|
9096
9096
|
}
|
|
9097
9097
|
async _createMessage(messages, params, options) {
|
|
9098
|
-
const
|
|
9099
|
-
if (
|
|
9100
|
-
if (
|
|
9098
|
+
const signal2 = options?.signal;
|
|
9099
|
+
if (signal2) {
|
|
9100
|
+
if (signal2.aborted)
|
|
9101
9101
|
this.controller.abort();
|
|
9102
|
-
|
|
9102
|
+
signal2.addEventListener("abort", () => this.controller.abort());
|
|
9103
9103
|
}
|
|
9104
9104
|
__classPrivateFieldGet9(this, _MessageStream_instances, "m", _MessageStream_beginRequest).call(this);
|
|
9105
9105
|
const { response, data: stream } = await messages.create({ ...params, stream: true }, { ...options, signal: this.controller.signal }).withResponse();
|
|
@@ -9213,11 +9213,11 @@ var init_MessageStream = __esm(() => {
|
|
|
9213
9213
|
}
|
|
9214
9214
|
}
|
|
9215
9215
|
async _fromReadableStream(readableStream, options) {
|
|
9216
|
-
const
|
|
9217
|
-
if (
|
|
9218
|
-
if (
|
|
9216
|
+
const signal2 = options?.signal;
|
|
9217
|
+
if (signal2) {
|
|
9218
|
+
if (signal2.aborted)
|
|
9219
9219
|
this.controller.abort();
|
|
9220
|
-
|
|
9220
|
+
signal2.addEventListener("abort", () => this.controller.abort());
|
|
9221
9221
|
}
|
|
9222
9222
|
__classPrivateFieldGet9(this, _MessageStream_instances, "m", _MessageStream_beginRequest).call(this);
|
|
9223
9223
|
this._connected(null);
|
|
@@ -9676,220 +9676,754 @@ Assistant:`;
|
|
|
9676
9676
|
|
|
9677
9677
|
// src/core/engine.ts
|
|
9678
9678
|
import { homedir as homedir2 } from "os";
|
|
9679
|
-
import { join as
|
|
9679
|
+
import { join as join2 } from "path";
|
|
9680
9680
|
|
|
9681
|
-
// node_modules/
|
|
9681
|
+
// node_modules/@rlabs-inc/fsdb/dist/index.mjs
|
|
9682
9682
|
import { watch } from "fs";
|
|
9683
|
-
|
|
9683
|
+
var equals = (oldValue, newValue) => Object.is(oldValue, newValue);
|
|
9684
|
+
var DERIVED = 1 << 1;
|
|
9685
|
+
var EFFECT = 1 << 2;
|
|
9686
|
+
var RENDER_EFFECT = 1 << 3;
|
|
9687
|
+
var ROOT_EFFECT = 1 << 4;
|
|
9688
|
+
var BRANCH_EFFECT = 1 << 5;
|
|
9689
|
+
var USER_EFFECT = 1 << 6;
|
|
9690
|
+
var BLOCK_EFFECT = 1 << 7;
|
|
9691
|
+
var CLEAN = 1 << 10;
|
|
9692
|
+
var DIRTY = 1 << 11;
|
|
9693
|
+
var MAYBE_DIRTY = 1 << 12;
|
|
9694
|
+
var REACTION_IS_UPDATING = 1 << 13;
|
|
9695
|
+
var DESTROYED = 1 << 14;
|
|
9696
|
+
var INERT = 1 << 15;
|
|
9697
|
+
var EFFECT_RAN = 1 << 16;
|
|
9698
|
+
var EFFECT_PRESERVED = 1 << 17;
|
|
9699
|
+
var UNOWNED = 1 << 8;
|
|
9700
|
+
var DISCONNECTED = 1 << 9;
|
|
9701
|
+
var INSPECT_EFFECT = 1 << 18;
|
|
9702
|
+
var UNINITIALIZED = Symbol.for("rlabs.signals.uninitialized");
|
|
9703
|
+
var STALE_REACTION = Symbol.for("rlabs.signals.stale_reaction");
|
|
9704
|
+
var STATE_SYMBOL = Symbol.for("rlabs.signals.state");
|
|
9705
|
+
var REACTIVE_MARKER = Symbol.for("rlabs.signals.reactive");
|
|
9706
|
+
var STATUS_MASK = ~(DIRTY | MAYBE_DIRTY | CLEAN);
|
|
9684
9707
|
var activeReaction = null;
|
|
9708
|
+
var activeEffect = null;
|
|
9709
|
+
var untracking = false;
|
|
9710
|
+
var writeVersion = 1;
|
|
9711
|
+
var readVersion = 0;
|
|
9712
|
+
var newDeps = null;
|
|
9713
|
+
var skippedDeps = 0;
|
|
9714
|
+
var untrackedWrites = null;
|
|
9685
9715
|
var batchDepth = 0;
|
|
9686
9716
|
var pendingReactions = new Set;
|
|
9687
|
-
var
|
|
9688
|
-
var
|
|
9689
|
-
|
|
9690
|
-
|
|
9691
|
-
|
|
9692
|
-
|
|
9693
|
-
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
|
|
9699
|
-
|
|
9700
|
-
|
|
9701
|
-
|
|
9702
|
-
|
|
9703
|
-
|
|
9717
|
+
var queuedRootEffects = [];
|
|
9718
|
+
var isFlushingSync = false;
|
|
9719
|
+
function setActiveReaction(reaction) {
|
|
9720
|
+
const prev = activeReaction;
|
|
9721
|
+
activeReaction = reaction;
|
|
9722
|
+
return prev;
|
|
9723
|
+
}
|
|
9724
|
+
function setActiveEffect(effect) {
|
|
9725
|
+
const prev = activeEffect;
|
|
9726
|
+
activeEffect = effect;
|
|
9727
|
+
return prev;
|
|
9728
|
+
}
|
|
9729
|
+
function incrementWriteVersion() {
|
|
9730
|
+
return ++writeVersion;
|
|
9731
|
+
}
|
|
9732
|
+
function incrementReadVersion() {
|
|
9733
|
+
return ++readVersion;
|
|
9734
|
+
}
|
|
9735
|
+
function setNewDeps(deps) {
|
|
9736
|
+
const prev = newDeps;
|
|
9737
|
+
newDeps = deps;
|
|
9738
|
+
return prev;
|
|
9739
|
+
}
|
|
9740
|
+
function setSkippedDeps(count) {
|
|
9741
|
+
const prev = skippedDeps;
|
|
9742
|
+
skippedDeps = count;
|
|
9743
|
+
return prev;
|
|
9744
|
+
}
|
|
9745
|
+
function setUntrackedWrites(writes) {
|
|
9746
|
+
const prev = untrackedWrites;
|
|
9747
|
+
untrackedWrites = writes;
|
|
9748
|
+
return prev;
|
|
9749
|
+
}
|
|
9750
|
+
function addUntrackedWrite(signal) {
|
|
9751
|
+
if (untrackedWrites === null) {
|
|
9752
|
+
untrackedWrites = [signal];
|
|
9753
|
+
} else {
|
|
9754
|
+
untrackedWrites.push(signal);
|
|
9755
|
+
}
|
|
9756
|
+
}
|
|
9757
|
+
function addPendingReaction(reaction) {
|
|
9758
|
+
pendingReactions.add(reaction);
|
|
9759
|
+
}
|
|
9760
|
+
function clearQueuedRootEffects() {
|
|
9761
|
+
const prev = queuedRootEffects;
|
|
9762
|
+
queuedRootEffects = [];
|
|
9763
|
+
return prev;
|
|
9764
|
+
}
|
|
9765
|
+
function addQueuedRootEffect(effect) {
|
|
9766
|
+
queuedRootEffects.push(effect);
|
|
9767
|
+
}
|
|
9768
|
+
function scheduleEffect(reaction) {
|
|
9769
|
+
addPendingReaction(reaction);
|
|
9770
|
+
if (batchDepth > 0) {
|
|
9771
|
+
return;
|
|
9772
|
+
}
|
|
9773
|
+
let effect = reaction;
|
|
9774
|
+
while (effect.parent !== null) {
|
|
9775
|
+
effect = effect.parent;
|
|
9776
|
+
const flags = effect.f;
|
|
9777
|
+
if ((flags & (ROOT_EFFECT | BRANCH_EFFECT)) !== 0) {
|
|
9778
|
+
if ((flags & CLEAN) === 0) {
|
|
9779
|
+
return;
|
|
9780
|
+
}
|
|
9781
|
+
effect.f ^= CLEAN;
|
|
9704
9782
|
}
|
|
9705
|
-
}
|
|
9706
|
-
|
|
9707
|
-
|
|
9708
|
-
|
|
9783
|
+
}
|
|
9784
|
+
addQueuedRootEffect(effect);
|
|
9785
|
+
if (!isFlushingSync) {
|
|
9786
|
+
queueMicrotask(flushEffects);
|
|
9787
|
+
}
|
|
9788
|
+
}
|
|
9789
|
+
var updateEffectImpl = () => {
|
|
9790
|
+
throw new Error("updateEffect not initialized - import effect.ts first");
|
|
9791
|
+
};
|
|
9792
|
+
function setUpdateEffectImpl(impl) {
|
|
9793
|
+
updateEffectImpl = impl;
|
|
9794
|
+
}
|
|
9795
|
+
function flushEffects() {
|
|
9796
|
+
const roots = clearQueuedRootEffects();
|
|
9797
|
+
for (const root of roots) {
|
|
9798
|
+
if (isDirty(root)) {
|
|
9799
|
+
updateEffectImpl(root);
|
|
9709
9800
|
}
|
|
9710
|
-
|
|
9711
|
-
|
|
9712
|
-
|
|
9713
|
-
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
|
|
9801
|
+
processEffectTree(root);
|
|
9802
|
+
}
|
|
9803
|
+
}
|
|
9804
|
+
function processEffectTree(effect) {
|
|
9805
|
+
let child = effect.first;
|
|
9806
|
+
while (child !== null) {
|
|
9807
|
+
const next = child.next;
|
|
9808
|
+
if (isDirty(child)) {
|
|
9809
|
+
updateEffectImpl(child);
|
|
9718
9810
|
}
|
|
9719
|
-
|
|
9720
|
-
|
|
9721
|
-
|
|
9722
|
-
|
|
9723
|
-
|
|
9724
|
-
|
|
9725
|
-
|
|
9726
|
-
|
|
9727
|
-
|
|
9728
|
-
|
|
9729
|
-
|
|
9730
|
-
|
|
9811
|
+
if (child.first !== null) {
|
|
9812
|
+
processEffectTree(child);
|
|
9813
|
+
}
|
|
9814
|
+
child = next;
|
|
9815
|
+
}
|
|
9816
|
+
}
|
|
9817
|
+
function get(signal) {
|
|
9818
|
+
if (activeReaction !== null && !untracking) {
|
|
9819
|
+
if ((activeReaction.f & REACTION_IS_UPDATING) !== 0) {
|
|
9820
|
+
if (signal.rv < readVersion) {
|
|
9821
|
+
signal.rv = readVersion;
|
|
9822
|
+
const deps = activeReaction.deps;
|
|
9823
|
+
if (newDeps === null && deps !== null && deps[skippedDeps] === signal) {
|
|
9824
|
+
setSkippedDeps(skippedDeps + 1);
|
|
9825
|
+
} else {
|
|
9826
|
+
if (newDeps === null) {
|
|
9827
|
+
setNewDeps([signal]);
|
|
9828
|
+
} else {
|
|
9829
|
+
newDeps.push(signal);
|
|
9830
|
+
}
|
|
9831
|
+
}
|
|
9832
|
+
}
|
|
9833
|
+
} else {
|
|
9834
|
+
if (activeReaction.deps === null) {
|
|
9835
|
+
activeReaction.deps = [signal];
|
|
9836
|
+
} else if (!activeReaction.deps.includes(signal)) {
|
|
9837
|
+
activeReaction.deps.push(signal);
|
|
9838
|
+
}
|
|
9839
|
+
if (signal.reactions === null) {
|
|
9840
|
+
signal.reactions = [activeReaction];
|
|
9841
|
+
} else if (!signal.reactions.includes(activeReaction)) {
|
|
9842
|
+
signal.reactions.push(activeReaction);
|
|
9731
9843
|
}
|
|
9732
|
-
return internal.v;
|
|
9733
9844
|
}
|
|
9734
|
-
}
|
|
9845
|
+
}
|
|
9846
|
+
if ((signal.f & DERIVED) !== 0) {
|
|
9847
|
+
const derived = signal;
|
|
9848
|
+
if (isDirty(derived)) {
|
|
9849
|
+
updateDerived(derived);
|
|
9850
|
+
}
|
|
9851
|
+
}
|
|
9852
|
+
return signal.v;
|
|
9735
9853
|
}
|
|
9736
|
-
|
|
9737
|
-
|
|
9738
|
-
|
|
9739
|
-
activeReaction.deps.add(signal2);
|
|
9740
|
-
signal2.reactions.add(activeReaction);
|
|
9854
|
+
function set(signal, value) {
|
|
9855
|
+
if (activeReaction !== null && (activeReaction.f & DERIVED) !== 0) {
|
|
9856
|
+
throw new Error("Cannot write to signals inside a derived. " + "Deriveds should be pure computations with no side effects.");
|
|
9741
9857
|
}
|
|
9858
|
+
if (!signal.equals(signal.v, value)) {
|
|
9859
|
+
signal.v = value;
|
|
9860
|
+
signal.wv = incrementWriteVersion();
|
|
9861
|
+
markReactions(signal, DIRTY);
|
|
9862
|
+
if (activeEffect !== null && (activeEffect.f & CLEAN) !== 0 && (activeEffect.f & (ROOT_EFFECT | BRANCH_EFFECT)) === 0) {
|
|
9863
|
+
addUntrackedWrite(signal);
|
|
9864
|
+
}
|
|
9865
|
+
}
|
|
9866
|
+
return value;
|
|
9742
9867
|
}
|
|
9743
|
-
function
|
|
9744
|
-
const reactions =
|
|
9745
|
-
|
|
9746
|
-
|
|
9747
|
-
|
|
9748
|
-
|
|
9749
|
-
|
|
9868
|
+
function markReactions(signal, status) {
|
|
9869
|
+
const reactions = signal.reactions;
|
|
9870
|
+
if (reactions === null)
|
|
9871
|
+
return;
|
|
9872
|
+
for (let i = 0;i < reactions.length; i++) {
|
|
9873
|
+
const reaction = reactions[i];
|
|
9874
|
+
const flags = reaction.f;
|
|
9875
|
+
const notDirty = (flags & DIRTY) === 0;
|
|
9876
|
+
if (notDirty) {
|
|
9877
|
+
setSignalStatus(reaction, status);
|
|
9878
|
+
}
|
|
9879
|
+
if ((flags & DERIVED) !== 0) {
|
|
9880
|
+
markReactions(reaction, MAYBE_DIRTY);
|
|
9881
|
+
} else if (notDirty) {
|
|
9882
|
+
scheduleEffect(reaction);
|
|
9883
|
+
}
|
|
9884
|
+
}
|
|
9885
|
+
}
|
|
9886
|
+
function setSignalStatus(signal, status) {
|
|
9887
|
+
signal.f = signal.f & STATUS_MASK | status;
|
|
9888
|
+
}
|
|
9889
|
+
function isDirty(reaction) {
|
|
9890
|
+
if ((reaction.f & DIRTY) !== 0) {
|
|
9891
|
+
return true;
|
|
9892
|
+
}
|
|
9893
|
+
if ((reaction.f & MAYBE_DIRTY) !== 0) {
|
|
9894
|
+
const deps = reaction.deps;
|
|
9895
|
+
if (deps !== null) {
|
|
9896
|
+
for (let i = 0;i < deps.length; i++) {
|
|
9897
|
+
const dep = deps[i];
|
|
9898
|
+
if ((dep.f & DERIVED) !== 0) {
|
|
9899
|
+
if (isDirty(dep)) {
|
|
9900
|
+
updateDerived(dep);
|
|
9901
|
+
}
|
|
9902
|
+
}
|
|
9903
|
+
if (dep.wv > reaction.wv) {
|
|
9904
|
+
return true;
|
|
9905
|
+
}
|
|
9906
|
+
}
|
|
9907
|
+
}
|
|
9908
|
+
setSignalStatus(reaction, CLEAN);
|
|
9909
|
+
}
|
|
9910
|
+
return false;
|
|
9911
|
+
}
|
|
9912
|
+
var updateDerivedImpl = () => {
|
|
9913
|
+
throw new Error("updateDerived not initialized - import derived.ts first");
|
|
9914
|
+
};
|
|
9915
|
+
function updateDerived(derived) {
|
|
9916
|
+
updateDerivedImpl(derived);
|
|
9917
|
+
}
|
|
9918
|
+
function setUpdateDerivedImpl(impl) {
|
|
9919
|
+
updateDerivedImpl = impl;
|
|
9920
|
+
}
|
|
9921
|
+
function removeReactions(reaction, start) {
|
|
9922
|
+
const deps = reaction.deps;
|
|
9923
|
+
if (deps === null)
|
|
9924
|
+
return;
|
|
9925
|
+
for (let i = start;i < deps.length; i++) {
|
|
9926
|
+
removeReaction(reaction, deps[i]);
|
|
9927
|
+
}
|
|
9928
|
+
}
|
|
9929
|
+
function removeReaction(reaction, dep) {
|
|
9930
|
+
const reactions = dep.reactions;
|
|
9931
|
+
if (reactions === null)
|
|
9932
|
+
return;
|
|
9933
|
+
const index = reactions.indexOf(reaction);
|
|
9934
|
+
if (index !== -1) {
|
|
9935
|
+
const last = reactions.length - 1;
|
|
9936
|
+
if (index !== last) {
|
|
9937
|
+
reactions[index] = reactions[last];
|
|
9938
|
+
}
|
|
9939
|
+
reactions.pop();
|
|
9940
|
+
if (reactions.length === 0) {
|
|
9941
|
+
dep.reactions = null;
|
|
9942
|
+
}
|
|
9943
|
+
}
|
|
9944
|
+
}
|
|
9945
|
+
function updateReaction(reaction) {
|
|
9946
|
+
const prevNewDeps = newDeps;
|
|
9947
|
+
const prevSkippedDeps = skippedDeps;
|
|
9948
|
+
const prevReaction = activeReaction;
|
|
9949
|
+
const prevUntrackedWrites = untrackedWrites;
|
|
9950
|
+
setNewDeps(null);
|
|
9951
|
+
setSkippedDeps(0);
|
|
9952
|
+
setActiveReaction(reaction);
|
|
9953
|
+
setUntrackedWrites(null);
|
|
9954
|
+
const prevReadVersion = readVersion;
|
|
9955
|
+
incrementReadVersion();
|
|
9956
|
+
reaction.f |= REACTION_IS_UPDATING;
|
|
9957
|
+
try {
|
|
9958
|
+
const result = reaction.fn();
|
|
9959
|
+
const deps = reaction.deps;
|
|
9960
|
+
if (newDeps !== null) {
|
|
9961
|
+
removeReactions(reaction, skippedDeps);
|
|
9962
|
+
if (deps !== null && skippedDeps > 0) {
|
|
9963
|
+
deps.length = skippedDeps + newDeps.length;
|
|
9964
|
+
for (let i = 0;i < newDeps.length; i++) {
|
|
9965
|
+
deps[skippedDeps + i] = newDeps[i];
|
|
9966
|
+
}
|
|
9967
|
+
} else {
|
|
9968
|
+
reaction.deps = newDeps;
|
|
9969
|
+
}
|
|
9970
|
+
const finalDeps = reaction.deps;
|
|
9971
|
+
for (let i = skippedDeps;i < finalDeps.length; i++) {
|
|
9972
|
+
const dep = finalDeps[i];
|
|
9973
|
+
if (dep.reactions === null) {
|
|
9974
|
+
dep.reactions = [reaction];
|
|
9975
|
+
} else {
|
|
9976
|
+
dep.reactions.push(reaction);
|
|
9977
|
+
}
|
|
9978
|
+
}
|
|
9979
|
+
} else if (deps !== null && skippedDeps < deps.length) {
|
|
9980
|
+
removeReactions(reaction, skippedDeps);
|
|
9981
|
+
deps.length = skippedDeps;
|
|
9982
|
+
}
|
|
9983
|
+
if (untrackedWrites !== null && reaction.deps !== null && (reaction.f & EFFECT) !== 0 && (reaction.f & DERIVED) === 0) {
|
|
9984
|
+
for (const signal of untrackedWrites) {
|
|
9985
|
+
if (reaction.deps.includes(signal)) {
|
|
9986
|
+
setSignalStatus(reaction, DIRTY);
|
|
9987
|
+
scheduleEffect(reaction);
|
|
9988
|
+
break;
|
|
9989
|
+
}
|
|
9990
|
+
}
|
|
9750
9991
|
}
|
|
9751
|
-
|
|
9752
|
-
|
|
9992
|
+
return result;
|
|
9993
|
+
} finally {
|
|
9994
|
+
reaction.f &= ~REACTION_IS_UPDATING;
|
|
9995
|
+
setNewDeps(prevNewDeps);
|
|
9996
|
+
setSkippedDeps(prevSkippedDeps);
|
|
9997
|
+
setActiveReaction(prevReaction);
|
|
9998
|
+
if (untrackedWrites !== null) {
|
|
9999
|
+
if (prevUntrackedWrites === null) {
|
|
10000
|
+
setUntrackedWrites(untrackedWrites);
|
|
10001
|
+
} else {
|
|
10002
|
+
prevUntrackedWrites.push(...untrackedWrites);
|
|
10003
|
+
setUntrackedWrites(prevUntrackedWrites);
|
|
10004
|
+
}
|
|
9753
10005
|
} else {
|
|
9754
|
-
|
|
10006
|
+
setUntrackedWrites(prevUntrackedWrites);
|
|
9755
10007
|
}
|
|
9756
10008
|
}
|
|
9757
10009
|
}
|
|
9758
|
-
|
|
9759
|
-
|
|
9760
|
-
|
|
10010
|
+
function source(initialValue, options) {
|
|
10011
|
+
return {
|
|
10012
|
+
f: 0,
|
|
10013
|
+
v: initialValue,
|
|
10014
|
+
equals: options?.equals ?? equals,
|
|
10015
|
+
reactions: null,
|
|
10016
|
+
rv: 0,
|
|
10017
|
+
wv: 0
|
|
10018
|
+
};
|
|
10019
|
+
}
|
|
10020
|
+
function signal(initialValue, options) {
|
|
10021
|
+
const src = source(initialValue, options);
|
|
10022
|
+
return {
|
|
10023
|
+
get value() {
|
|
10024
|
+
return get(src);
|
|
10025
|
+
},
|
|
10026
|
+
set value(newValue) {
|
|
10027
|
+
set(src, newValue);
|
|
10028
|
+
}
|
|
10029
|
+
};
|
|
10030
|
+
}
|
|
10031
|
+
var proxyFn = null;
|
|
10032
|
+
function setProxyFn(fn) {
|
|
10033
|
+
proxyFn = fn;
|
|
9761
10034
|
}
|
|
9762
10035
|
function shouldProxy(value) {
|
|
9763
|
-
if (value === null || typeof value !== "object")
|
|
9764
|
-
return false;
|
|
9765
|
-
if (value[REACTIVE_MARKER])
|
|
10036
|
+
if (value === null || typeof value !== "object") {
|
|
9766
10037
|
return false;
|
|
10038
|
+
}
|
|
9767
10039
|
const proto = Object.getPrototypeOf(value);
|
|
9768
10040
|
return proto === Object.prototype || proto === Array.prototype || proto === null;
|
|
9769
10041
|
}
|
|
9770
|
-
function
|
|
9771
|
-
|
|
9772
|
-
|
|
9773
|
-
|
|
9774
|
-
const
|
|
9775
|
-
|
|
9776
|
-
|
|
9777
|
-
|
|
10042
|
+
function isProxy(value) {
|
|
10043
|
+
return value !== null && typeof value === "object" && STATE_SYMBOL in value;
|
|
10044
|
+
}
|
|
10045
|
+
function isWritable(target, prop) {
|
|
10046
|
+
const descriptor = Object.getOwnPropertyDescriptor(target, prop);
|
|
10047
|
+
return descriptor === undefined || descriptor.writable === true;
|
|
10048
|
+
}
|
|
10049
|
+
function proxy(value) {
|
|
10050
|
+
if (!shouldProxy(value) || isProxy(value)) {
|
|
10051
|
+
return value;
|
|
10052
|
+
}
|
|
10053
|
+
const sources = new Map;
|
|
10054
|
+
const version = source(0);
|
|
10055
|
+
const isArray = Array.isArray(value);
|
|
10056
|
+
if (isArray) {
|
|
10057
|
+
sources.set("length", source(value.length));
|
|
10058
|
+
}
|
|
10059
|
+
const parentReadVersion = readVersion;
|
|
10060
|
+
const withParent = (fn) => {
|
|
10061
|
+
if (readVersion === parentReadVersion) {
|
|
10062
|
+
return fn();
|
|
10063
|
+
}
|
|
10064
|
+
const prevReaction = activeReaction;
|
|
10065
|
+
setActiveReaction(null);
|
|
10066
|
+
try {
|
|
10067
|
+
return fn();
|
|
10068
|
+
} finally {
|
|
10069
|
+
setActiveReaction(prevReaction);
|
|
10070
|
+
}
|
|
9778
10071
|
};
|
|
9779
|
-
const
|
|
9780
|
-
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
|
|
9785
|
-
|
|
9786
|
-
|
|
9787
|
-
};
|
|
9788
|
-
propSignals.set(prop, sig);
|
|
10072
|
+
const getSource = (prop, initialValue) => {
|
|
10073
|
+
let s = sources.get(prop);
|
|
10074
|
+
if (s === undefined) {
|
|
10075
|
+
s = withParent(() => {
|
|
10076
|
+
const proxied = shouldProxy(initialValue) ? proxy(initialValue) : initialValue;
|
|
10077
|
+
return source(proxied);
|
|
10078
|
+
});
|
|
10079
|
+
sources.set(prop, s);
|
|
9789
10080
|
}
|
|
9790
|
-
return
|
|
10081
|
+
return s;
|
|
9791
10082
|
};
|
|
9792
|
-
const
|
|
9793
|
-
get(
|
|
9794
|
-
if (prop ===
|
|
9795
|
-
return
|
|
9796
|
-
const value = Reflect.get(target2, prop, receiver);
|
|
9797
|
-
if (Array.isArray(target2) && typeof value === "function") {
|
|
9798
|
-
track(internal);
|
|
9799
|
-
return value.bind(proxy);
|
|
9800
|
-
}
|
|
9801
|
-
const sig = getPropSignal(prop);
|
|
9802
|
-
track(sig);
|
|
9803
|
-
if (shouldProxy(value)) {
|
|
9804
|
-
const existingProxy = rawToProxy.get(value);
|
|
9805
|
-
if (existingProxy)
|
|
9806
|
-
return existingProxy;
|
|
9807
|
-
return createDeepReactive(value);
|
|
10083
|
+
const proxyObj = new Proxy(value, {
|
|
10084
|
+
get(target, prop, receiver) {
|
|
10085
|
+
if (prop === STATE_SYMBOL) {
|
|
10086
|
+
return value;
|
|
9808
10087
|
}
|
|
9809
|
-
|
|
10088
|
+
const exists = prop in target;
|
|
10089
|
+
const currentValue = Reflect.get(target, prop, receiver);
|
|
10090
|
+
if (isArray && typeof currentValue === "function") {
|
|
10091
|
+
get(version);
|
|
10092
|
+
return currentValue.bind(proxyObj);
|
|
10093
|
+
}
|
|
10094
|
+
if (exists || isWritable(target, prop)) {
|
|
10095
|
+
const s = getSource(prop, currentValue);
|
|
10096
|
+
const val = get(s);
|
|
10097
|
+
if (val === UNINITIALIZED) {
|
|
10098
|
+
return;
|
|
10099
|
+
}
|
|
10100
|
+
return val;
|
|
10101
|
+
}
|
|
10102
|
+
return currentValue;
|
|
9810
10103
|
},
|
|
9811
|
-
set(
|
|
9812
|
-
const
|
|
9813
|
-
|
|
9814
|
-
if (
|
|
9815
|
-
|
|
9816
|
-
|
|
9817
|
-
|
|
9818
|
-
|
|
9819
|
-
|
|
9820
|
-
|
|
9821
|
-
|
|
9822
|
-
|
|
9823
|
-
|
|
10104
|
+
set(target, prop, newValue, receiver) {
|
|
10105
|
+
const exists = prop in target;
|
|
10106
|
+
let s = sources.get(prop);
|
|
10107
|
+
if (s === undefined) {
|
|
10108
|
+
if (!exists && !isWritable(target, prop)) {
|
|
10109
|
+
return false;
|
|
10110
|
+
}
|
|
10111
|
+
s = withParent(() => source(undefined));
|
|
10112
|
+
sources.set(prop, s);
|
|
10113
|
+
}
|
|
10114
|
+
const proxied = withParent(() => shouldProxy(newValue) ? proxy(newValue) : newValue);
|
|
10115
|
+
set(s, proxied);
|
|
10116
|
+
Reflect.set(target, prop, newValue, receiver);
|
|
10117
|
+
if (isArray && prop === "length") {
|
|
10118
|
+
const oldLength = s.v;
|
|
10119
|
+
const newLength = newValue;
|
|
10120
|
+
for (let i = newLength;i < oldLength; i++) {
|
|
10121
|
+
const indexKey = String(i);
|
|
10122
|
+
const indexSource = sources.get(indexKey);
|
|
10123
|
+
if (indexSource !== undefined) {
|
|
10124
|
+
set(indexSource, UNINITIALIZED);
|
|
10125
|
+
} else if (i in target) {
|
|
10126
|
+
const deletedSource = withParent(() => source(UNINITIALIZED));
|
|
10127
|
+
sources.set(indexKey, deletedSource);
|
|
10128
|
+
}
|
|
9824
10129
|
}
|
|
9825
10130
|
}
|
|
9826
|
-
|
|
10131
|
+
if (isArray && typeof prop === "string") {
|
|
10132
|
+
const index = Number(prop);
|
|
10133
|
+
if (Number.isInteger(index) && index >= 0) {
|
|
10134
|
+
const lengthSource = sources.get("length");
|
|
10135
|
+
if (lengthSource !== undefined && index >= lengthSource.v) {
|
|
10136
|
+
set(lengthSource, index + 1);
|
|
10137
|
+
}
|
|
10138
|
+
}
|
|
10139
|
+
}
|
|
10140
|
+
if (!exists) {
|
|
10141
|
+
set(version, get(version) + 1);
|
|
10142
|
+
}
|
|
10143
|
+
return true;
|
|
9827
10144
|
},
|
|
9828
|
-
deleteProperty(
|
|
9829
|
-
const
|
|
9830
|
-
|
|
9831
|
-
|
|
9832
|
-
|
|
9833
|
-
|
|
9834
|
-
|
|
9835
|
-
|
|
10145
|
+
deleteProperty(target, prop) {
|
|
10146
|
+
const exists = prop in target;
|
|
10147
|
+
if (exists) {
|
|
10148
|
+
let s = sources.get(prop);
|
|
10149
|
+
if (s === undefined) {
|
|
10150
|
+
s = withParent(() => source(UNINITIALIZED));
|
|
10151
|
+
sources.set(prop, s);
|
|
10152
|
+
} else {
|
|
10153
|
+
set(s, UNINITIALIZED);
|
|
9836
10154
|
}
|
|
9837
|
-
|
|
10155
|
+
set(version, get(version) + 1);
|
|
9838
10156
|
}
|
|
9839
|
-
return
|
|
10157
|
+
return Reflect.deleteProperty(target, prop);
|
|
9840
10158
|
},
|
|
9841
|
-
has(
|
|
9842
|
-
if (prop ===
|
|
10159
|
+
has(target, prop) {
|
|
10160
|
+
if (prop === STATE_SYMBOL) {
|
|
9843
10161
|
return true;
|
|
9844
|
-
|
|
9845
|
-
|
|
10162
|
+
}
|
|
10163
|
+
get(version);
|
|
10164
|
+
const s = sources.get(prop);
|
|
10165
|
+
if (s !== undefined) {
|
|
10166
|
+
const val = get(s);
|
|
10167
|
+
if (val === UNINITIALIZED) {
|
|
10168
|
+
return false;
|
|
10169
|
+
}
|
|
10170
|
+
}
|
|
10171
|
+
return Reflect.has(target, prop);
|
|
9846
10172
|
},
|
|
9847
|
-
ownKeys(
|
|
9848
|
-
|
|
9849
|
-
|
|
10173
|
+
ownKeys(target) {
|
|
10174
|
+
get(version);
|
|
10175
|
+
const keys = Reflect.ownKeys(target).filter((key) => {
|
|
10176
|
+
const s = sources.get(key);
|
|
10177
|
+
return s === undefined || s.v !== UNINITIALIZED;
|
|
10178
|
+
});
|
|
10179
|
+
for (const [key, s] of sources) {
|
|
10180
|
+
const k = key;
|
|
10181
|
+
if (s.v !== UNINITIALIZED && !(key in target) && !keys.includes(k)) {
|
|
10182
|
+
keys.push(k);
|
|
10183
|
+
}
|
|
10184
|
+
}
|
|
10185
|
+
return keys;
|
|
10186
|
+
},
|
|
10187
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
10188
|
+
const s = sources.get(prop);
|
|
10189
|
+
if (s !== undefined && s.v === UNINITIALIZED) {
|
|
10190
|
+
return;
|
|
10191
|
+
}
|
|
10192
|
+
return Reflect.getOwnPropertyDescriptor(target, prop);
|
|
9850
10193
|
}
|
|
9851
10194
|
});
|
|
9852
|
-
|
|
9853
|
-
|
|
9854
|
-
|
|
9855
|
-
|
|
10195
|
+
return proxyObj;
|
|
10196
|
+
}
|
|
10197
|
+
function createDerived(fn, options) {
|
|
10198
|
+
let flags = DERIVED | DIRTY;
|
|
10199
|
+
const parentDerived = activeReaction !== null && (activeReaction.f & DERIVED) !== 0 ? activeReaction : null;
|
|
10200
|
+
if (activeEffect === null || parentDerived !== null && (parentDerived.f & UNOWNED) !== 0) {
|
|
10201
|
+
flags |= UNOWNED;
|
|
10202
|
+
}
|
|
10203
|
+
const derived = {
|
|
10204
|
+
f: flags,
|
|
10205
|
+
fn,
|
|
10206
|
+
v: UNINITIALIZED,
|
|
10207
|
+
equals: options?.equals ?? equals,
|
|
10208
|
+
reactions: null,
|
|
10209
|
+
deps: null,
|
|
10210
|
+
effects: null,
|
|
10211
|
+
parent: parentDerived ?? activeEffect,
|
|
10212
|
+
rv: 0,
|
|
10213
|
+
wv: 0
|
|
10214
|
+
};
|
|
10215
|
+
return derived;
|
|
10216
|
+
}
|
|
10217
|
+
function executeDerived(derived) {
|
|
10218
|
+
destroyDerivedEffects(derived);
|
|
10219
|
+
const value = updateReaction(derived);
|
|
10220
|
+
return value;
|
|
10221
|
+
}
|
|
10222
|
+
function updateDerived2(derived) {
|
|
10223
|
+
const value = executeDerived(derived);
|
|
10224
|
+
if (!derived.equals(derived.v, value)) {
|
|
10225
|
+
derived.v = value;
|
|
10226
|
+
derived.wv = incrementWriteVersion();
|
|
10227
|
+
}
|
|
10228
|
+
const status = (derived.f & UNOWNED) !== 0 && derived.deps !== null ? MAYBE_DIRTY : CLEAN;
|
|
10229
|
+
setSignalStatus(derived, status);
|
|
10230
|
+
}
|
|
10231
|
+
setUpdateDerivedImpl(updateDerived2);
|
|
10232
|
+
var destroyEffectImpl = () => {};
|
|
10233
|
+
function setDestroyEffectImpl(impl) {
|
|
10234
|
+
destroyEffectImpl = impl;
|
|
10235
|
+
}
|
|
10236
|
+
function destroyDerivedEffects(derived) {
|
|
10237
|
+
const effects = derived.effects;
|
|
10238
|
+
if (effects !== null) {
|
|
10239
|
+
derived.effects = null;
|
|
10240
|
+
for (let i = 0;i < effects.length; i++) {
|
|
10241
|
+
destroyEffectImpl(effects[i]);
|
|
10242
|
+
}
|
|
10243
|
+
}
|
|
10244
|
+
}
|
|
10245
|
+
function derived(fn, options) {
|
|
10246
|
+
const d = createDerived(fn, options);
|
|
10247
|
+
return {
|
|
10248
|
+
get value() {
|
|
10249
|
+
return get(d);
|
|
10250
|
+
}
|
|
10251
|
+
};
|
|
10252
|
+
}
|
|
10253
|
+
derived.by = derived;
|
|
10254
|
+
function createEffect(type, fn, sync, push = true) {
|
|
10255
|
+
const parent = activeEffect;
|
|
10256
|
+
const effect = {
|
|
10257
|
+
f: type | DIRTY,
|
|
10258
|
+
fn,
|
|
10259
|
+
deps: null,
|
|
10260
|
+
teardown: null,
|
|
10261
|
+
parent,
|
|
10262
|
+
first: null,
|
|
10263
|
+
last: null,
|
|
10264
|
+
prev: null,
|
|
10265
|
+
next: null,
|
|
10266
|
+
wv: 0
|
|
10267
|
+
};
|
|
10268
|
+
if (sync) {
|
|
10269
|
+
updateEffect(effect);
|
|
10270
|
+
effect.f |= EFFECT_RAN;
|
|
10271
|
+
} else if (fn !== null) {
|
|
10272
|
+
scheduleEffect(effect);
|
|
10273
|
+
}
|
|
10274
|
+
if (push && parent !== null) {
|
|
10275
|
+
pushEffect(effect, parent);
|
|
10276
|
+
}
|
|
10277
|
+
return effect;
|
|
10278
|
+
}
|
|
10279
|
+
function pushEffect(effect, parent) {
|
|
10280
|
+
const parentLast = parent.last;
|
|
10281
|
+
if (parentLast === null) {
|
|
10282
|
+
parent.first = parent.last = effect;
|
|
10283
|
+
} else {
|
|
10284
|
+
parentLast.next = effect;
|
|
10285
|
+
effect.prev = parentLast;
|
|
10286
|
+
parent.last = effect;
|
|
10287
|
+
}
|
|
9856
10288
|
}
|
|
9857
|
-
|
|
9858
|
-
|
|
10289
|
+
function updateEffect(effect) {
|
|
10290
|
+
if ((effect.f & DESTROYED) !== 0)
|
|
10291
|
+
return;
|
|
10292
|
+
setSignalStatus(effect, CLEAN);
|
|
10293
|
+
const prevEffect = activeEffect;
|
|
10294
|
+
setActiveEffect(effect);
|
|
10295
|
+
try {
|
|
10296
|
+
destroyEffectChildren(effect);
|
|
10297
|
+
executeTeardown(effect);
|
|
10298
|
+
const teardown = updateReaction(effect);
|
|
10299
|
+
effect.teardown = typeof teardown === "function" ? teardown : null;
|
|
10300
|
+
effect.wv = incrementWriteVersion();
|
|
10301
|
+
} finally {
|
|
10302
|
+
setActiveEffect(prevEffect);
|
|
10303
|
+
}
|
|
10304
|
+
}
|
|
10305
|
+
setUpdateEffectImpl(updateEffect);
|
|
10306
|
+
function destroyEffect(effect, removeFromParent = true) {
|
|
10307
|
+
destroyEffectChildren(effect);
|
|
10308
|
+
removeReactions(effect, 0);
|
|
10309
|
+
setSignalStatus(effect, DESTROYED);
|
|
10310
|
+
executeTeardown(effect);
|
|
10311
|
+
if (removeFromParent && effect.parent !== null) {
|
|
10312
|
+
unlinkEffect(effect);
|
|
10313
|
+
}
|
|
10314
|
+
effect.fn = null;
|
|
10315
|
+
effect.teardown = null;
|
|
10316
|
+
effect.deps = null;
|
|
10317
|
+
effect.first = null;
|
|
10318
|
+
effect.last = null;
|
|
10319
|
+
effect.prev = null;
|
|
10320
|
+
effect.next = null;
|
|
10321
|
+
}
|
|
10322
|
+
setDestroyEffectImpl(destroyEffect);
|
|
10323
|
+
function destroyEffectChildren(effect) {
|
|
10324
|
+
let child = effect.first;
|
|
10325
|
+
effect.first = null;
|
|
10326
|
+
effect.last = null;
|
|
10327
|
+
while (child !== null) {
|
|
10328
|
+
const next = child.next;
|
|
10329
|
+
if ((child.f & (EFFECT_PRESERVED | ROOT_EFFECT)) === 0) {
|
|
10330
|
+
destroyEffect(child, false);
|
|
10331
|
+
}
|
|
10332
|
+
child = next;
|
|
10333
|
+
}
|
|
10334
|
+
}
|
|
10335
|
+
function executeTeardown(effect) {
|
|
10336
|
+
const teardown = effect.teardown;
|
|
10337
|
+
if (teardown !== null) {
|
|
10338
|
+
effect.teardown = null;
|
|
10339
|
+
teardown();
|
|
10340
|
+
}
|
|
10341
|
+
}
|
|
10342
|
+
function unlinkEffect(effect) {
|
|
10343
|
+
const { parent, prev, next } = effect;
|
|
10344
|
+
if (prev !== null) {
|
|
10345
|
+
prev.next = next;
|
|
10346
|
+
}
|
|
10347
|
+
if (next !== null) {
|
|
10348
|
+
next.prev = prev;
|
|
10349
|
+
}
|
|
10350
|
+
if (parent !== null) {
|
|
10351
|
+
if (parent.first === effect) {
|
|
10352
|
+
parent.first = next;
|
|
10353
|
+
}
|
|
10354
|
+
if (parent.last === effect) {
|
|
10355
|
+
parent.last = prev;
|
|
10356
|
+
}
|
|
10357
|
+
}
|
|
10358
|
+
effect.prev = null;
|
|
10359
|
+
effect.next = null;
|
|
10360
|
+
}
|
|
10361
|
+
function effect(fn) {
|
|
10362
|
+
const eff = createEffect(EFFECT | USER_EFFECT, fn, false);
|
|
10363
|
+
return () => destroyEffect(eff);
|
|
10364
|
+
}
|
|
10365
|
+
effect.pre = function effectPre(fn) {
|
|
10366
|
+
const eff = createEffect(RENDER_EFFECT | USER_EFFECT, fn, true);
|
|
10367
|
+
return () => destroyEffect(eff);
|
|
10368
|
+
};
|
|
10369
|
+
effect.root = function effectRoot(fn) {
|
|
10370
|
+
const eff = createEffect(ROOT_EFFECT | EFFECT_PRESERVED, fn, true);
|
|
10371
|
+
return () => destroyEffect(eff);
|
|
10372
|
+
};
|
|
10373
|
+
effect.tracking = function effectTracking() {
|
|
10374
|
+
return activeEffect !== null;
|
|
10375
|
+
};
|
|
9859
10376
|
|
|
9860
10377
|
class ReactiveMap extends Map {
|
|
9861
10378
|
#keySignals = new Map;
|
|
9862
|
-
#version =
|
|
9863
|
-
#size
|
|
10379
|
+
#version = source(0);
|
|
10380
|
+
#size;
|
|
9864
10381
|
constructor(entries) {
|
|
9865
|
-
super();
|
|
9866
|
-
|
|
9867
|
-
for (const [key, value] of entries) {
|
|
9868
|
-
super.set(key, value);
|
|
9869
|
-
}
|
|
9870
|
-
this.#size.v = super.size;
|
|
9871
|
-
}
|
|
10382
|
+
super(entries);
|
|
10383
|
+
this.#size = source(super.size);
|
|
9872
10384
|
}
|
|
9873
10385
|
#getKeySignal(key) {
|
|
9874
10386
|
let sig = this.#keySignals.get(key);
|
|
9875
|
-
if (
|
|
9876
|
-
sig =
|
|
10387
|
+
if (sig === undefined) {
|
|
10388
|
+
sig = source(0);
|
|
9877
10389
|
this.#keySignals.set(key, sig);
|
|
9878
10390
|
}
|
|
9879
10391
|
return sig;
|
|
9880
10392
|
}
|
|
10393
|
+
#increment(sig) {
|
|
10394
|
+
set(sig, sig.v + 1);
|
|
10395
|
+
}
|
|
9881
10396
|
get size() {
|
|
9882
|
-
|
|
10397
|
+
get(this.#size);
|
|
9883
10398
|
return super.size;
|
|
9884
10399
|
}
|
|
9885
10400
|
has(key) {
|
|
9886
|
-
const sig = this.#
|
|
9887
|
-
|
|
10401
|
+
const sig = this.#keySignals.get(key);
|
|
10402
|
+
if (sig === undefined) {
|
|
10403
|
+
if (!super.has(key)) {
|
|
10404
|
+
get(this.#version);
|
|
10405
|
+
return false;
|
|
10406
|
+
}
|
|
10407
|
+
const newSig = this.#getKeySignal(key);
|
|
10408
|
+
get(newSig);
|
|
10409
|
+
return true;
|
|
10410
|
+
}
|
|
10411
|
+
get(sig);
|
|
9888
10412
|
return super.has(key);
|
|
9889
10413
|
}
|
|
9890
10414
|
get(key) {
|
|
9891
|
-
const sig = this.#
|
|
9892
|
-
|
|
10415
|
+
const sig = this.#keySignals.get(key);
|
|
10416
|
+
if (sig === undefined) {
|
|
10417
|
+
const val = super.get(key);
|
|
10418
|
+
if (val !== undefined) {
|
|
10419
|
+
const newSig = this.#getKeySignal(key);
|
|
10420
|
+
get(newSig);
|
|
10421
|
+
return val;
|
|
10422
|
+
}
|
|
10423
|
+
get(this.#version);
|
|
10424
|
+
return;
|
|
10425
|
+
}
|
|
10426
|
+
get(sig);
|
|
9893
10427
|
return super.get(key);
|
|
9894
10428
|
}
|
|
9895
10429
|
set(key, value) {
|
|
@@ -9898,65 +10432,60 @@ class ReactiveMap extends Map {
|
|
|
9898
10432
|
super.set(key, value);
|
|
9899
10433
|
const sig = this.#getKeySignal(key);
|
|
9900
10434
|
if (isNew) {
|
|
9901
|
-
this.#size
|
|
9902
|
-
|
|
9903
|
-
this.#
|
|
9904
|
-
trigger(this.#version);
|
|
9905
|
-
sig.v++;
|
|
9906
|
-
trigger(sig);
|
|
10435
|
+
set(this.#size, super.size);
|
|
10436
|
+
this.#increment(this.#version);
|
|
10437
|
+
this.#increment(sig);
|
|
9907
10438
|
} else if (!Object.is(oldValue, value)) {
|
|
9908
|
-
sig
|
|
9909
|
-
|
|
10439
|
+
this.#increment(sig);
|
|
10440
|
+
const versionReactions = this.#version.reactions;
|
|
10441
|
+
const keyReactions = sig.reactions;
|
|
10442
|
+
if (keyReactions !== null && (versionReactions === null || !keyReactions.every((r) => versionReactions.includes(r)))) {
|
|
10443
|
+
this.#increment(this.#version);
|
|
10444
|
+
}
|
|
9910
10445
|
}
|
|
9911
10446
|
return this;
|
|
9912
10447
|
}
|
|
9913
10448
|
delete(key) {
|
|
9914
|
-
const
|
|
9915
|
-
|
|
9916
|
-
|
|
10449
|
+
const existed = super.has(key);
|
|
10450
|
+
if (existed) {
|
|
10451
|
+
super.delete(key);
|
|
9917
10452
|
const sig = this.#keySignals.get(key);
|
|
9918
|
-
if (sig) {
|
|
9919
|
-
sig
|
|
9920
|
-
trigger(sig);
|
|
10453
|
+
if (sig !== undefined) {
|
|
10454
|
+
set(sig, -1);
|
|
9921
10455
|
this.#keySignals.delete(key);
|
|
9922
10456
|
}
|
|
9923
|
-
this.#size
|
|
9924
|
-
|
|
9925
|
-
this.#version.v++;
|
|
9926
|
-
trigger(this.#version);
|
|
10457
|
+
set(this.#size, super.size);
|
|
10458
|
+
this.#increment(this.#version);
|
|
9927
10459
|
}
|
|
9928
|
-
return
|
|
10460
|
+
return existed;
|
|
9929
10461
|
}
|
|
9930
10462
|
clear() {
|
|
9931
|
-
if (super.size
|
|
9932
|
-
|
|
9933
|
-
|
|
9934
|
-
|
|
9935
|
-
|
|
10463
|
+
if (super.size > 0) {
|
|
10464
|
+
for (const [key, sig] of this.#keySignals) {
|
|
10465
|
+
set(sig, -1);
|
|
10466
|
+
}
|
|
10467
|
+
this.#keySignals.clear();
|
|
10468
|
+
super.clear();
|
|
10469
|
+
set(this.#size, 0);
|
|
10470
|
+
this.#increment(this.#version);
|
|
9936
10471
|
}
|
|
9937
|
-
super.clear();
|
|
9938
|
-
this.#keySignals.clear();
|
|
9939
|
-
this.#size.v = 0;
|
|
9940
|
-
trigger(this.#size);
|
|
9941
|
-
this.#version.v++;
|
|
9942
|
-
trigger(this.#version);
|
|
9943
|
-
}
|
|
9944
|
-
forEach(callbackfn, thisArg) {
|
|
9945
|
-
track(this.#version);
|
|
9946
|
-
super.forEach(callbackfn, thisArg);
|
|
9947
10472
|
}
|
|
9948
10473
|
keys() {
|
|
9949
|
-
|
|
10474
|
+
get(this.#version);
|
|
9950
10475
|
return super.keys();
|
|
9951
10476
|
}
|
|
9952
10477
|
values() {
|
|
9953
|
-
|
|
10478
|
+
get(this.#version);
|
|
9954
10479
|
return super.values();
|
|
9955
10480
|
}
|
|
9956
10481
|
entries() {
|
|
9957
|
-
|
|
10482
|
+
get(this.#version);
|
|
9958
10483
|
return super.entries();
|
|
9959
10484
|
}
|
|
10485
|
+
forEach(callbackfn, thisArg) {
|
|
10486
|
+
get(this.#version);
|
|
10487
|
+
super.forEach(callbackfn, thisArg);
|
|
10488
|
+
}
|
|
9960
10489
|
[Symbol.iterator]() {
|
|
9961
10490
|
return this.entries();
|
|
9962
10491
|
}
|
|
@@ -9964,375 +10493,857 @@ class ReactiveMap extends Map {
|
|
|
9964
10493
|
|
|
9965
10494
|
class ReactiveSet extends Set {
|
|
9966
10495
|
#itemSignals = new Map;
|
|
9967
|
-
#version =
|
|
9968
|
-
#size
|
|
10496
|
+
#version = source(0);
|
|
10497
|
+
#size;
|
|
9969
10498
|
constructor(values) {
|
|
9970
|
-
super();
|
|
9971
|
-
|
|
9972
|
-
for (const value of values) {
|
|
9973
|
-
super.add(value);
|
|
9974
|
-
}
|
|
9975
|
-
this.#size.v = super.size;
|
|
9976
|
-
}
|
|
10499
|
+
super(values);
|
|
10500
|
+
this.#size = source(super.size);
|
|
9977
10501
|
}
|
|
9978
10502
|
#getItemSignal(item) {
|
|
9979
10503
|
let sig = this.#itemSignals.get(item);
|
|
9980
|
-
if (
|
|
9981
|
-
sig =
|
|
10504
|
+
if (sig === undefined) {
|
|
10505
|
+
sig = source(super.has(item));
|
|
9982
10506
|
this.#itemSignals.set(item, sig);
|
|
9983
10507
|
}
|
|
9984
10508
|
return sig;
|
|
9985
10509
|
}
|
|
10510
|
+
#incrementVersion() {
|
|
10511
|
+
set(this.#version, this.#version.v + 1);
|
|
10512
|
+
}
|
|
9986
10513
|
get size() {
|
|
9987
|
-
|
|
10514
|
+
get(this.#size);
|
|
9988
10515
|
return super.size;
|
|
9989
10516
|
}
|
|
9990
|
-
has(
|
|
9991
|
-
const sig = this.#
|
|
9992
|
-
|
|
9993
|
-
|
|
9994
|
-
|
|
9995
|
-
|
|
9996
|
-
|
|
9997
|
-
|
|
9998
|
-
|
|
9999
|
-
|
|
10000
|
-
|
|
10001
|
-
|
|
10002
|
-
|
|
10003
|
-
|
|
10004
|
-
|
|
10517
|
+
has(item) {
|
|
10518
|
+
const sig = this.#itemSignals.get(item);
|
|
10519
|
+
if (sig === undefined) {
|
|
10520
|
+
const exists = super.has(item);
|
|
10521
|
+
if (exists) {
|
|
10522
|
+
const newSig = this.#getItemSignal(item);
|
|
10523
|
+
get(newSig);
|
|
10524
|
+
return true;
|
|
10525
|
+
}
|
|
10526
|
+
get(this.#version);
|
|
10527
|
+
return false;
|
|
10528
|
+
}
|
|
10529
|
+
get(sig);
|
|
10530
|
+
return super.has(item);
|
|
10531
|
+
}
|
|
10532
|
+
add(item) {
|
|
10533
|
+
const isNew = !super.has(item);
|
|
10534
|
+
super.add(item);
|
|
10535
|
+
if (isNew) {
|
|
10536
|
+
const sig = this.#getItemSignal(item);
|
|
10537
|
+
set(sig, true);
|
|
10538
|
+
set(this.#size, super.size);
|
|
10539
|
+
this.#incrementVersion();
|
|
10005
10540
|
}
|
|
10006
10541
|
return this;
|
|
10007
10542
|
}
|
|
10008
|
-
delete(
|
|
10009
|
-
const
|
|
10010
|
-
|
|
10011
|
-
|
|
10012
|
-
const sig = this.#itemSignals.get(
|
|
10013
|
-
if (sig) {
|
|
10014
|
-
sig
|
|
10015
|
-
|
|
10016
|
-
|
|
10017
|
-
|
|
10018
|
-
this.#
|
|
10019
|
-
trigger(this.#size);
|
|
10020
|
-
this.#version.v++;
|
|
10021
|
-
trigger(this.#version);
|
|
10543
|
+
delete(item) {
|
|
10544
|
+
const existed = super.has(item);
|
|
10545
|
+
if (existed) {
|
|
10546
|
+
super.delete(item);
|
|
10547
|
+
const sig = this.#itemSignals.get(item);
|
|
10548
|
+
if (sig !== undefined) {
|
|
10549
|
+
set(sig, false);
|
|
10550
|
+
this.#itemSignals.delete(item);
|
|
10551
|
+
}
|
|
10552
|
+
set(this.#size, super.size);
|
|
10553
|
+
this.#incrementVersion();
|
|
10022
10554
|
}
|
|
10023
|
-
return
|
|
10555
|
+
return existed;
|
|
10024
10556
|
}
|
|
10025
10557
|
clear() {
|
|
10026
|
-
if (super.size
|
|
10027
|
-
|
|
10028
|
-
|
|
10029
|
-
|
|
10030
|
-
|
|
10558
|
+
if (super.size > 0) {
|
|
10559
|
+
for (const [item, sig] of this.#itemSignals) {
|
|
10560
|
+
set(sig, false);
|
|
10561
|
+
}
|
|
10562
|
+
this.#itemSignals.clear();
|
|
10563
|
+
super.clear();
|
|
10564
|
+
set(this.#size, 0);
|
|
10565
|
+
this.#incrementVersion();
|
|
10031
10566
|
}
|
|
10032
|
-
super.clear();
|
|
10033
|
-
this.#itemSignals.clear();
|
|
10034
|
-
this.#size.v = 0;
|
|
10035
|
-
trigger(this.#size);
|
|
10036
|
-
this.#version.v++;
|
|
10037
|
-
trigger(this.#version);
|
|
10038
|
-
}
|
|
10039
|
-
forEach(callbackfn, thisArg) {
|
|
10040
|
-
track(this.#version);
|
|
10041
|
-
super.forEach(callbackfn, thisArg);
|
|
10042
10567
|
}
|
|
10043
10568
|
keys() {
|
|
10044
|
-
|
|
10569
|
+
get(this.#version);
|
|
10045
10570
|
return super.keys();
|
|
10046
10571
|
}
|
|
10047
10572
|
values() {
|
|
10048
|
-
|
|
10573
|
+
get(this.#version);
|
|
10049
10574
|
return super.values();
|
|
10050
10575
|
}
|
|
10051
10576
|
entries() {
|
|
10052
|
-
|
|
10577
|
+
get(this.#version);
|
|
10053
10578
|
return super.entries();
|
|
10054
10579
|
}
|
|
10580
|
+
forEach(callbackfn, thisArg) {
|
|
10581
|
+
get(this.#version);
|
|
10582
|
+
super.forEach(callbackfn, thisArg);
|
|
10583
|
+
}
|
|
10055
10584
|
[Symbol.iterator]() {
|
|
10056
10585
|
return this.values();
|
|
10057
10586
|
}
|
|
10058
10587
|
}
|
|
10059
|
-
|
|
10060
|
-
|
|
10061
|
-
|
|
10062
|
-
|
|
10063
|
-
|
|
10064
|
-
|
|
10065
|
-
get count() {
|
|
10066
|
-
return this.allocatedIndices.size;
|
|
10588
|
+
|
|
10589
|
+
class ReactiveDate extends Date {
|
|
10590
|
+
#time;
|
|
10591
|
+
constructor(...args) {
|
|
10592
|
+
super(...args);
|
|
10593
|
+
this.#time = source(super.getTime());
|
|
10067
10594
|
}
|
|
10068
|
-
|
|
10069
|
-
|
|
10070
|
-
|
|
10071
|
-
|
|
10072
|
-
return existing;
|
|
10073
|
-
let index;
|
|
10074
|
-
if (registry.freeIndices.length > 0) {
|
|
10075
|
-
index = registry.freeIndices.pop();
|
|
10076
|
-
} else {
|
|
10077
|
-
index = registry.nextIndex++;
|
|
10595
|
+
#update() {
|
|
10596
|
+
const time = super.getTime();
|
|
10597
|
+
set(this.#time, time);
|
|
10598
|
+
return time;
|
|
10078
10599
|
}
|
|
10079
|
-
|
|
10080
|
-
|
|
10081
|
-
|
|
10082
|
-
return index;
|
|
10083
|
-
}
|
|
10084
|
-
function releaseIndex(id) {
|
|
10085
|
-
const index = registry.idToIndex.get(id);
|
|
10086
|
-
if (index === undefined)
|
|
10087
|
-
return;
|
|
10088
|
-
registry.idToIndex.delete(id);
|
|
10089
|
-
registry.indexToId.delete(index);
|
|
10090
|
-
registry.allocatedIndices.delete(index);
|
|
10091
|
-
registry.freeIndices.push(index);
|
|
10092
|
-
return index;
|
|
10093
|
-
}
|
|
10094
|
-
function getIndex(id) {
|
|
10095
|
-
return registry.idToIndex.get(id);
|
|
10096
|
-
}
|
|
10097
|
-
function getId(index) {
|
|
10098
|
-
return registry.indexToId.get(index);
|
|
10099
|
-
}
|
|
10100
|
-
function getAllIndices() {
|
|
10101
|
-
return Array.from(registry.allocatedIndices);
|
|
10102
|
-
}
|
|
10103
|
-
function resetRegistry() {
|
|
10104
|
-
registry.idToIndex.clear();
|
|
10105
|
-
registry.indexToId.clear();
|
|
10106
|
-
registry.allocatedIndices.clear();
|
|
10107
|
-
registry.freeIndices.length = 0;
|
|
10108
|
-
registry.nextIndex = 0;
|
|
10109
|
-
}
|
|
10110
|
-
function parseColumnType(type) {
|
|
10111
|
-
if (type === "string" || type === "timestamp") {
|
|
10112
|
-
return { baseType: "string" };
|
|
10600
|
+
getTime() {
|
|
10601
|
+
get(this.#time);
|
|
10602
|
+
return super.getTime();
|
|
10113
10603
|
}
|
|
10114
|
-
|
|
10115
|
-
|
|
10604
|
+
getFullYear() {
|
|
10605
|
+
get(this.#time);
|
|
10606
|
+
return super.getFullYear();
|
|
10116
10607
|
}
|
|
10117
|
-
|
|
10118
|
-
|
|
10608
|
+
getMonth() {
|
|
10609
|
+
get(this.#time);
|
|
10610
|
+
return super.getMonth();
|
|
10119
10611
|
}
|
|
10120
|
-
|
|
10121
|
-
|
|
10612
|
+
getDate() {
|
|
10613
|
+
get(this.#time);
|
|
10614
|
+
return super.getDate();
|
|
10122
10615
|
}
|
|
10123
|
-
|
|
10124
|
-
|
|
10616
|
+
getDay() {
|
|
10617
|
+
get(this.#time);
|
|
10618
|
+
return super.getDay();
|
|
10125
10619
|
}
|
|
10126
|
-
|
|
10127
|
-
|
|
10128
|
-
return
|
|
10620
|
+
getHours() {
|
|
10621
|
+
get(this.#time);
|
|
10622
|
+
return super.getHours();
|
|
10129
10623
|
}
|
|
10130
|
-
|
|
10131
|
-
|
|
10132
|
-
|
|
10133
|
-
const columns = Object.keys(definition);
|
|
10134
|
-
const vectorColumns = columns.filter((col) => {
|
|
10135
|
-
const type = definition[col];
|
|
10136
|
-
return typeof type === "string" && type.startsWith("vector:");
|
|
10137
|
-
});
|
|
10138
|
-
return {
|
|
10139
|
-
definition,
|
|
10140
|
-
columns,
|
|
10141
|
-
vectorColumns
|
|
10142
|
-
};
|
|
10143
|
-
}
|
|
10144
|
-
function getDefaultForType(type) {
|
|
10145
|
-
const parsed = parseColumnType(type);
|
|
10146
|
-
switch (parsed.baseType) {
|
|
10147
|
-
case "string":
|
|
10148
|
-
return "";
|
|
10149
|
-
case "number":
|
|
10150
|
-
return 0;
|
|
10151
|
-
case "boolean":
|
|
10152
|
-
return false;
|
|
10153
|
-
case "array":
|
|
10154
|
-
return [];
|
|
10155
|
-
case "vector":
|
|
10156
|
-
return null;
|
|
10157
|
-
default:
|
|
10158
|
-
return null;
|
|
10624
|
+
getMinutes() {
|
|
10625
|
+
get(this.#time);
|
|
10626
|
+
return super.getMinutes();
|
|
10159
10627
|
}
|
|
10160
|
-
|
|
10161
|
-
|
|
10162
|
-
|
|
10163
|
-
_arrays = new ReactiveMap;
|
|
10164
|
-
_indexes = new ReactiveMap;
|
|
10165
|
-
_schema;
|
|
10166
|
-
constructor(schema) {
|
|
10167
|
-
this._schema = schema;
|
|
10168
|
-
for (const name of Object.keys(schema)) {
|
|
10169
|
-
this._arrays.set(name, []);
|
|
10170
|
-
}
|
|
10628
|
+
getSeconds() {
|
|
10629
|
+
get(this.#time);
|
|
10630
|
+
return super.getSeconds();
|
|
10171
10631
|
}
|
|
10172
|
-
|
|
10173
|
-
|
|
10632
|
+
getMilliseconds() {
|
|
10633
|
+
get(this.#time);
|
|
10634
|
+
return super.getMilliseconds();
|
|
10174
10635
|
}
|
|
10175
|
-
|
|
10176
|
-
|
|
10177
|
-
|
|
10178
|
-
this._updateIndex(column, index, value);
|
|
10636
|
+
getUTCFullYear() {
|
|
10637
|
+
get(this.#time);
|
|
10638
|
+
return super.getUTCFullYear();
|
|
10179
10639
|
}
|
|
10180
|
-
|
|
10181
|
-
|
|
10640
|
+
getUTCMonth() {
|
|
10641
|
+
get(this.#time);
|
|
10642
|
+
return super.getUTCMonth();
|
|
10182
10643
|
}
|
|
10183
|
-
|
|
10184
|
-
|
|
10185
|
-
|
|
10186
|
-
|
|
10187
|
-
|
|
10644
|
+
getUTCDate() {
|
|
10645
|
+
get(this.#time);
|
|
10646
|
+
return super.getUTCDate();
|
|
10647
|
+
}
|
|
10648
|
+
getUTCDay() {
|
|
10649
|
+
get(this.#time);
|
|
10650
|
+
return super.getUTCDay();
|
|
10651
|
+
}
|
|
10652
|
+
getUTCHours() {
|
|
10653
|
+
get(this.#time);
|
|
10654
|
+
return super.getUTCHours();
|
|
10655
|
+
}
|
|
10656
|
+
getUTCMinutes() {
|
|
10657
|
+
get(this.#time);
|
|
10658
|
+
return super.getUTCMinutes();
|
|
10659
|
+
}
|
|
10660
|
+
getUTCSeconds() {
|
|
10661
|
+
get(this.#time);
|
|
10662
|
+
return super.getUTCSeconds();
|
|
10663
|
+
}
|
|
10664
|
+
getUTCMilliseconds() {
|
|
10665
|
+
get(this.#time);
|
|
10666
|
+
return super.getUTCMilliseconds();
|
|
10667
|
+
}
|
|
10668
|
+
getTimezoneOffset() {
|
|
10669
|
+
get(this.#time);
|
|
10670
|
+
return super.getTimezoneOffset();
|
|
10671
|
+
}
|
|
10672
|
+
setTime(time) {
|
|
10673
|
+
super.setTime(time);
|
|
10674
|
+
return this.#update();
|
|
10675
|
+
}
|
|
10676
|
+
setFullYear(year, month, date) {
|
|
10677
|
+
if (date !== undefined) {
|
|
10678
|
+
super.setFullYear(year, month, date);
|
|
10679
|
+
} else if (month !== undefined) {
|
|
10680
|
+
super.setFullYear(year, month);
|
|
10681
|
+
} else {
|
|
10682
|
+
super.setFullYear(year);
|
|
10188
10683
|
}
|
|
10684
|
+
return this.#update();
|
|
10189
10685
|
}
|
|
10190
|
-
|
|
10191
|
-
|
|
10192
|
-
|
|
10193
|
-
|
|
10686
|
+
setMonth(month, date) {
|
|
10687
|
+
if (date !== undefined) {
|
|
10688
|
+
super.setMonth(month, date);
|
|
10689
|
+
} else {
|
|
10690
|
+
super.setMonth(month);
|
|
10194
10691
|
}
|
|
10195
|
-
return
|
|
10692
|
+
return this.#update();
|
|
10196
10693
|
}
|
|
10197
|
-
|
|
10198
|
-
|
|
10199
|
-
|
|
10200
|
-
|
|
10201
|
-
|
|
10202
|
-
|
|
10203
|
-
|
|
10204
|
-
|
|
10205
|
-
|
|
10206
|
-
|
|
10207
|
-
|
|
10208
|
-
|
|
10209
|
-
|
|
10210
|
-
break;
|
|
10211
|
-
case "array":
|
|
10212
|
-
arr[index] = [];
|
|
10213
|
-
break;
|
|
10214
|
-
case "vector":
|
|
10215
|
-
arr[index] = null;
|
|
10216
|
-
break;
|
|
10217
|
-
}
|
|
10694
|
+
setDate(date) {
|
|
10695
|
+
super.setDate(date);
|
|
10696
|
+
return this.#update();
|
|
10697
|
+
}
|
|
10698
|
+
setHours(hours, min, sec, ms) {
|
|
10699
|
+
if (ms !== undefined) {
|
|
10700
|
+
super.setHours(hours, min, sec, ms);
|
|
10701
|
+
} else if (sec !== undefined) {
|
|
10702
|
+
super.setHours(hours, min, sec);
|
|
10703
|
+
} else if (min !== undefined) {
|
|
10704
|
+
super.setHours(hours, min);
|
|
10705
|
+
} else {
|
|
10706
|
+
super.setHours(hours);
|
|
10218
10707
|
}
|
|
10708
|
+
return this.#update();
|
|
10219
10709
|
}
|
|
10220
|
-
|
|
10221
|
-
if (
|
|
10222
|
-
|
|
10710
|
+
setMinutes(min, sec, ms) {
|
|
10711
|
+
if (ms !== undefined) {
|
|
10712
|
+
super.setMinutes(min, sec, ms);
|
|
10713
|
+
} else if (sec !== undefined) {
|
|
10714
|
+
super.setMinutes(min, sec);
|
|
10715
|
+
} else {
|
|
10716
|
+
super.setMinutes(min);
|
|
10223
10717
|
}
|
|
10224
|
-
|
|
10225
|
-
|
|
10226
|
-
|
|
10227
|
-
|
|
10228
|
-
|
|
10229
|
-
|
|
10230
|
-
|
|
10231
|
-
|
|
10232
|
-
|
|
10233
|
-
|
|
10718
|
+
return this.#update();
|
|
10719
|
+
}
|
|
10720
|
+
setSeconds(sec, ms) {
|
|
10721
|
+
if (ms !== undefined) {
|
|
10722
|
+
super.setSeconds(sec, ms);
|
|
10723
|
+
} else {
|
|
10724
|
+
super.setSeconds(sec);
|
|
10725
|
+
}
|
|
10726
|
+
return this.#update();
|
|
10727
|
+
}
|
|
10728
|
+
setMilliseconds(ms) {
|
|
10729
|
+
super.setMilliseconds(ms);
|
|
10730
|
+
return this.#update();
|
|
10731
|
+
}
|
|
10732
|
+
setUTCFullYear(year, month, date) {
|
|
10733
|
+
if (date !== undefined) {
|
|
10734
|
+
super.setUTCFullYear(year, month, date);
|
|
10735
|
+
} else if (month !== undefined) {
|
|
10736
|
+
super.setUTCFullYear(year, month);
|
|
10737
|
+
} else {
|
|
10738
|
+
super.setUTCFullYear(year);
|
|
10739
|
+
}
|
|
10740
|
+
return this.#update();
|
|
10741
|
+
}
|
|
10742
|
+
setUTCMonth(month, date) {
|
|
10743
|
+
if (date !== undefined) {
|
|
10744
|
+
super.setUTCMonth(month, date);
|
|
10745
|
+
} else {
|
|
10746
|
+
super.setUTCMonth(month);
|
|
10747
|
+
}
|
|
10748
|
+
return this.#update();
|
|
10749
|
+
}
|
|
10750
|
+
setUTCDate(date) {
|
|
10751
|
+
super.setUTCDate(date);
|
|
10752
|
+
return this.#update();
|
|
10753
|
+
}
|
|
10754
|
+
setUTCHours(hours, min, sec, ms) {
|
|
10755
|
+
if (ms !== undefined) {
|
|
10756
|
+
super.setUTCHours(hours, min, sec, ms);
|
|
10757
|
+
} else if (sec !== undefined) {
|
|
10758
|
+
super.setUTCHours(hours, min, sec);
|
|
10759
|
+
} else if (min !== undefined) {
|
|
10760
|
+
super.setUTCHours(hours, min);
|
|
10761
|
+
} else {
|
|
10762
|
+
super.setUTCHours(hours);
|
|
10763
|
+
}
|
|
10764
|
+
return this.#update();
|
|
10765
|
+
}
|
|
10766
|
+
setUTCMinutes(min, sec, ms) {
|
|
10767
|
+
if (ms !== undefined) {
|
|
10768
|
+
super.setUTCMinutes(min, sec, ms);
|
|
10769
|
+
} else if (sec !== undefined) {
|
|
10770
|
+
super.setUTCMinutes(min, sec);
|
|
10771
|
+
} else {
|
|
10772
|
+
super.setUTCMinutes(min);
|
|
10773
|
+
}
|
|
10774
|
+
return this.#update();
|
|
10775
|
+
}
|
|
10776
|
+
setUTCSeconds(sec, ms) {
|
|
10777
|
+
if (ms !== undefined) {
|
|
10778
|
+
super.setUTCSeconds(sec, ms);
|
|
10779
|
+
} else {
|
|
10780
|
+
super.setUTCSeconds(sec);
|
|
10781
|
+
}
|
|
10782
|
+
return this.#update();
|
|
10783
|
+
}
|
|
10784
|
+
setUTCMilliseconds(ms) {
|
|
10785
|
+
super.setUTCMilliseconds(ms);
|
|
10786
|
+
return this.#update();
|
|
10787
|
+
}
|
|
10788
|
+
toString() {
|
|
10789
|
+
get(this.#time);
|
|
10790
|
+
return super.toString();
|
|
10791
|
+
}
|
|
10792
|
+
toDateString() {
|
|
10793
|
+
get(this.#time);
|
|
10794
|
+
return super.toDateString();
|
|
10795
|
+
}
|
|
10796
|
+
toTimeString() {
|
|
10797
|
+
get(this.#time);
|
|
10798
|
+
return super.toTimeString();
|
|
10799
|
+
}
|
|
10800
|
+
toISOString() {
|
|
10801
|
+
get(this.#time);
|
|
10802
|
+
return super.toISOString();
|
|
10803
|
+
}
|
|
10804
|
+
toUTCString() {
|
|
10805
|
+
get(this.#time);
|
|
10806
|
+
return super.toUTCString();
|
|
10807
|
+
}
|
|
10808
|
+
toLocaleString(locales, options) {
|
|
10809
|
+
get(this.#time);
|
|
10810
|
+
return super.toLocaleString(locales, options);
|
|
10811
|
+
}
|
|
10812
|
+
toLocaleDateString(locales, options) {
|
|
10813
|
+
get(this.#time);
|
|
10814
|
+
return super.toLocaleDateString(locales, options);
|
|
10815
|
+
}
|
|
10816
|
+
toLocaleTimeString(locales, options) {
|
|
10817
|
+
get(this.#time);
|
|
10818
|
+
return super.toLocaleTimeString(locales, options);
|
|
10819
|
+
}
|
|
10820
|
+
toJSON() {
|
|
10821
|
+
get(this.#time);
|
|
10822
|
+
return super.toJSON();
|
|
10823
|
+
}
|
|
10824
|
+
valueOf() {
|
|
10825
|
+
get(this.#time);
|
|
10826
|
+
return super.valueOf();
|
|
10827
|
+
}
|
|
10828
|
+
}
|
|
10829
|
+
setProxyFn(proxy);
|
|
10830
|
+
function createRegistry() {
|
|
10831
|
+
const idToIndex = new ReactiveMap;
|
|
10832
|
+
const indexToId = new ReactiveMap;
|
|
10833
|
+
const allocatedIndices = new ReactiveSet;
|
|
10834
|
+
const freeIndices = [];
|
|
10835
|
+
const _nextIndex = signal(0);
|
|
10836
|
+
const registry = {
|
|
10837
|
+
idToIndex,
|
|
10838
|
+
indexToId,
|
|
10839
|
+
allocatedIndices,
|
|
10840
|
+
freeIndices,
|
|
10841
|
+
get nextIndex() {
|
|
10842
|
+
return _nextIndex.value;
|
|
10843
|
+
},
|
|
10844
|
+
set nextIndex(value) {
|
|
10845
|
+
_nextIndex.value = value;
|
|
10846
|
+
},
|
|
10847
|
+
allocate(id) {
|
|
10848
|
+
const existingIndex = idToIndex.get(id);
|
|
10849
|
+
if (existingIndex !== undefined) {
|
|
10850
|
+
return existingIndex;
|
|
10851
|
+
}
|
|
10852
|
+
let index;
|
|
10853
|
+
if (freeIndices.length > 0) {
|
|
10854
|
+
index = freeIndices.pop();
|
|
10855
|
+
} else {
|
|
10856
|
+
index = _nextIndex.value;
|
|
10857
|
+
_nextIndex.value++;
|
|
10858
|
+
}
|
|
10859
|
+
idToIndex.set(id, index);
|
|
10860
|
+
indexToId.set(index, id);
|
|
10861
|
+
allocatedIndices.add(index);
|
|
10862
|
+
return index;
|
|
10863
|
+
},
|
|
10864
|
+
release(id) {
|
|
10865
|
+
const index = idToIndex.get(id);
|
|
10866
|
+
if (index === undefined) {
|
|
10867
|
+
return false;
|
|
10234
10868
|
}
|
|
10869
|
+
idToIndex.delete(id);
|
|
10870
|
+
indexToId.delete(index);
|
|
10871
|
+
allocatedIndices.delete(index);
|
|
10872
|
+
freeIndices.push(index);
|
|
10873
|
+
return true;
|
|
10874
|
+
},
|
|
10875
|
+
getIndex(id) {
|
|
10876
|
+
return idToIndex.get(id) ?? -1;
|
|
10877
|
+
},
|
|
10878
|
+
getId(index) {
|
|
10879
|
+
return indexToId.get(index);
|
|
10880
|
+
},
|
|
10881
|
+
has(id) {
|
|
10882
|
+
return idToIndex.has(id);
|
|
10883
|
+
},
|
|
10884
|
+
getAllIds() {
|
|
10885
|
+
return Array.from(idToIndex.keys());
|
|
10886
|
+
},
|
|
10887
|
+
getAllIndices() {
|
|
10888
|
+
return Array.from(allocatedIndices);
|
|
10889
|
+
},
|
|
10890
|
+
get count() {
|
|
10891
|
+
return idToIndex.size;
|
|
10892
|
+
},
|
|
10893
|
+
reset() {
|
|
10894
|
+
idToIndex.clear();
|
|
10895
|
+
indexToId.clear();
|
|
10896
|
+
allocatedIndices.clear();
|
|
10897
|
+
freeIndices.length = 0;
|
|
10898
|
+
_nextIndex.value = 0;
|
|
10235
10899
|
}
|
|
10236
|
-
|
|
10900
|
+
};
|
|
10901
|
+
return registry;
|
|
10902
|
+
}
|
|
10903
|
+
function generateId() {
|
|
10904
|
+
const timestamp = Date.now();
|
|
10905
|
+
const random = Math.random().toString(36).substring(2, 8);
|
|
10906
|
+
return `${timestamp}-${random}`;
|
|
10907
|
+
}
|
|
10908
|
+
var DEFAULT_VALUES = {
|
|
10909
|
+
string: "",
|
|
10910
|
+
number: 0,
|
|
10911
|
+
boolean: false,
|
|
10912
|
+
timestamp: 0,
|
|
10913
|
+
"string[]": [],
|
|
10914
|
+
"number[]": [],
|
|
10915
|
+
vector: null
|
|
10916
|
+
};
|
|
10917
|
+
var WATCHER_DEBOUNCE_MS = 100;
|
|
10918
|
+
var SAVE_GRACE_PERIOD_MS = 200;
|
|
10919
|
+
function parseColumnType(type) {
|
|
10920
|
+
if (type === "string")
|
|
10921
|
+
return { baseType: "string" };
|
|
10922
|
+
if (type === "number")
|
|
10923
|
+
return { baseType: "number" };
|
|
10924
|
+
if (type === "boolean")
|
|
10925
|
+
return { baseType: "boolean" };
|
|
10926
|
+
if (type === "timestamp")
|
|
10927
|
+
return { baseType: "timestamp" };
|
|
10928
|
+
if (type === "string[]")
|
|
10929
|
+
return { baseType: "array", arrayType: "string" };
|
|
10930
|
+
if (type === "number[]")
|
|
10931
|
+
return { baseType: "array", arrayType: "number" };
|
|
10932
|
+
const vectorMatch = type.match(/^vector:(\d+)$/);
|
|
10933
|
+
if (vectorMatch) {
|
|
10934
|
+
return {
|
|
10935
|
+
baseType: "vector",
|
|
10936
|
+
vectorDimensions: parseInt(vectorMatch[1], 10)
|
|
10937
|
+
};
|
|
10237
10938
|
}
|
|
10238
|
-
|
|
10239
|
-
|
|
10240
|
-
|
|
10241
|
-
|
|
10939
|
+
throw new Error(`Unknown column type: ${type}`);
|
|
10940
|
+
}
|
|
10941
|
+
function getDefaultValue(type) {
|
|
10942
|
+
const parsed = parseColumnType(type);
|
|
10943
|
+
switch (parsed.baseType) {
|
|
10944
|
+
case "string":
|
|
10945
|
+
return DEFAULT_VALUES.string;
|
|
10946
|
+
case "number":
|
|
10947
|
+
case "timestamp":
|
|
10948
|
+
return DEFAULT_VALUES.number;
|
|
10949
|
+
case "boolean":
|
|
10950
|
+
return DEFAULT_VALUES.boolean;
|
|
10951
|
+
case "array":
|
|
10952
|
+
return parsed.arrayType === "string" ? [...DEFAULT_VALUES["string[]"]] : [...DEFAULT_VALUES["number[]"]];
|
|
10953
|
+
case "vector":
|
|
10954
|
+
return DEFAULT_VALUES.vector;
|
|
10955
|
+
default:
|
|
10956
|
+
return null;
|
|
10957
|
+
}
|
|
10958
|
+
}
|
|
10959
|
+
function parseSchema(definition) {
|
|
10960
|
+
const columns = Object.keys(definition);
|
|
10961
|
+
const vectorColumns = [];
|
|
10962
|
+
const parsedTypes = new Map;
|
|
10963
|
+
for (const col of columns) {
|
|
10964
|
+
const parsed = parseColumnType(definition[col]);
|
|
10965
|
+
parsedTypes.set(col, parsed);
|
|
10966
|
+
if (parsed.baseType === "vector") {
|
|
10967
|
+
vectorColumns.push(col);
|
|
10242
10968
|
}
|
|
10243
|
-
return index.get(value) || [];
|
|
10244
10969
|
}
|
|
10245
|
-
|
|
10246
|
-
|
|
10247
|
-
|
|
10248
|
-
|
|
10249
|
-
|
|
10250
|
-
|
|
10970
|
+
return {
|
|
10971
|
+
definition,
|
|
10972
|
+
columns,
|
|
10973
|
+
vectorColumns,
|
|
10974
|
+
parsedTypes
|
|
10975
|
+
};
|
|
10976
|
+
}
|
|
10977
|
+
function createColumns(definition) {
|
|
10978
|
+
const schema = parseSchema(definition);
|
|
10979
|
+
const columns = new Map;
|
|
10980
|
+
for (const col of schema.columns) {
|
|
10981
|
+
columns.set(col, signal([]));
|
|
10982
|
+
}
|
|
10983
|
+
const manager = {
|
|
10984
|
+
schema,
|
|
10985
|
+
getColumn(name) {
|
|
10986
|
+
const col = columns.get(name);
|
|
10987
|
+
if (!col) {
|
|
10988
|
+
throw new Error(`Unknown column: ${String(name)}`);
|
|
10989
|
+
}
|
|
10990
|
+
return col;
|
|
10991
|
+
},
|
|
10992
|
+
get(column, index) {
|
|
10993
|
+
const col = columns.get(column);
|
|
10994
|
+
if (!col) {
|
|
10995
|
+
throw new Error(`Unknown column: ${String(column)}`);
|
|
10996
|
+
}
|
|
10997
|
+
return col.value[index];
|
|
10998
|
+
},
|
|
10999
|
+
set(column, index, value) {
|
|
11000
|
+
const col = columns.get(column);
|
|
11001
|
+
if (!col) {
|
|
11002
|
+
throw new Error(`Unknown column: ${String(column)}`);
|
|
11003
|
+
}
|
|
11004
|
+
const parsed = schema.parsedTypes.get(column);
|
|
11005
|
+
if (parsed?.baseType === "vector" && Array.isArray(value)) {
|
|
11006
|
+
value = new Float32Array(value);
|
|
11007
|
+
}
|
|
11008
|
+
const arr = col.value;
|
|
11009
|
+
while (arr.length <= index) {
|
|
11010
|
+
arr.push(getDefaultValue(definition[column]));
|
|
11011
|
+
}
|
|
11012
|
+
arr[index] = value;
|
|
11013
|
+
col.value = arr;
|
|
11014
|
+
},
|
|
11015
|
+
getRecord(index) {
|
|
11016
|
+
const record = {};
|
|
11017
|
+
for (const col of schema.columns) {
|
|
11018
|
+
record[col] = manager.get(col, index);
|
|
11019
|
+
}
|
|
11020
|
+
return record;
|
|
11021
|
+
},
|
|
11022
|
+
setRecord(index, record) {
|
|
11023
|
+
for (const col of schema.columns) {
|
|
11024
|
+
if (col in record) {
|
|
11025
|
+
manager.set(col, index, record[col]);
|
|
11026
|
+
} else {
|
|
11027
|
+
const defaultValue = getDefaultValue(definition[col]);
|
|
11028
|
+
manager.set(col, index, defaultValue);
|
|
11029
|
+
}
|
|
11030
|
+
}
|
|
11031
|
+
},
|
|
11032
|
+
clearAt(index) {
|
|
11033
|
+
for (const col of schema.columns) {
|
|
11034
|
+
const defaultValue = getDefaultValue(definition[col]);
|
|
11035
|
+
manager.set(col, index, defaultValue);
|
|
11036
|
+
}
|
|
11037
|
+
},
|
|
11038
|
+
reset() {
|
|
11039
|
+
for (const col of schema.columns) {
|
|
11040
|
+
const colSignal = columns.get(col);
|
|
11041
|
+
if (colSignal) {
|
|
11042
|
+
colSignal.value = [];
|
|
11043
|
+
}
|
|
10251
11044
|
}
|
|
10252
11045
|
}
|
|
10253
|
-
|
|
11046
|
+
};
|
|
11047
|
+
return manager;
|
|
11048
|
+
}
|
|
11049
|
+
function createMetadataArrays() {
|
|
11050
|
+
return {
|
|
11051
|
+
created: signal([]),
|
|
11052
|
+
updated: signal([]),
|
|
11053
|
+
stale: signal([])
|
|
11054
|
+
};
|
|
11055
|
+
}
|
|
11056
|
+
function createCollection(name, options) {
|
|
11057
|
+
const { schema, contentColumn } = options;
|
|
11058
|
+
const registry = createRegistry();
|
|
11059
|
+
const columns = createColumns(schema);
|
|
11060
|
+
const metadata = createMetadataArrays();
|
|
11061
|
+
function buildRecord(index) {
|
|
11062
|
+
const id = registry.getId(index);
|
|
11063
|
+
if (!id)
|
|
11064
|
+
throw new Error(`No ID for index ${index}`);
|
|
11065
|
+
const data = columns.getRecord(index);
|
|
11066
|
+
return {
|
|
11067
|
+
...data,
|
|
11068
|
+
id,
|
|
11069
|
+
created: metadata.created.value[index] ?? 0,
|
|
11070
|
+
updated: metadata.updated.value[index] ?? 0,
|
|
11071
|
+
stale: metadata.stale.value[index] ?? false
|
|
11072
|
+
};
|
|
10254
11073
|
}
|
|
10255
|
-
|
|
10256
|
-
const
|
|
10257
|
-
|
|
11074
|
+
function setMetadataAt(index, created, updated, stale) {
|
|
11075
|
+
const createdArr = metadata.created.value;
|
|
11076
|
+
const updatedArr = metadata.updated.value;
|
|
11077
|
+
const staleArr = metadata.stale.value;
|
|
11078
|
+
while (createdArr.length <= index)
|
|
11079
|
+
createdArr.push(0);
|
|
11080
|
+
while (updatedArr.length <= index)
|
|
11081
|
+
updatedArr.push(0);
|
|
11082
|
+
while (staleArr.length <= index)
|
|
11083
|
+
staleArr.push(false);
|
|
11084
|
+
createdArr[index] = created;
|
|
11085
|
+
updatedArr[index] = updated;
|
|
11086
|
+
staleArr[index] = stale;
|
|
11087
|
+
metadata.created.value = createdArr;
|
|
11088
|
+
metadata.updated.value = updatedArr;
|
|
11089
|
+
metadata.stale.value = staleArr;
|
|
11090
|
+
}
|
|
11091
|
+
const collection = {
|
|
11092
|
+
name,
|
|
11093
|
+
schema,
|
|
11094
|
+
contentColumn,
|
|
11095
|
+
registry,
|
|
11096
|
+
columns,
|
|
11097
|
+
insert(data) {
|
|
11098
|
+
const id = data.id ?? generateId();
|
|
11099
|
+
const index = registry.allocate(id);
|
|
11100
|
+
const now = Date.now();
|
|
11101
|
+
columns.setRecord(index, data);
|
|
11102
|
+
setMetadataAt(index, now, now, false);
|
|
11103
|
+
return id;
|
|
11104
|
+
},
|
|
11105
|
+
insertMany(records) {
|
|
11106
|
+
return records.map((record) => collection.insert(record));
|
|
11107
|
+
},
|
|
11108
|
+
get(id) {
|
|
11109
|
+
const index = registry.getIndex(id);
|
|
11110
|
+
if (index === -1)
|
|
11111
|
+
return;
|
|
11112
|
+
return buildRecord(index);
|
|
11113
|
+
},
|
|
11114
|
+
all() {
|
|
11115
|
+
const indices = registry.getAllIndices();
|
|
11116
|
+
return indices.map((index) => buildRecord(index));
|
|
11117
|
+
},
|
|
11118
|
+
find(filter) {
|
|
11119
|
+
const results = [];
|
|
11120
|
+
const indices = registry.getAllIndices();
|
|
11121
|
+
for (const index of indices) {
|
|
11122
|
+
const data = columns.getRecord(index);
|
|
11123
|
+
if (filter(data, index)) {
|
|
11124
|
+
results.push(buildRecord(index));
|
|
11125
|
+
}
|
|
11126
|
+
}
|
|
11127
|
+
return results;
|
|
11128
|
+
},
|
|
11129
|
+
findOne(filter) {
|
|
11130
|
+
const indices = registry.getAllIndices();
|
|
11131
|
+
for (const index of indices) {
|
|
11132
|
+
const data = columns.getRecord(index);
|
|
11133
|
+
if (filter(data, index)) {
|
|
11134
|
+
return buildRecord(index);
|
|
11135
|
+
}
|
|
11136
|
+
}
|
|
10258
11137
|
return;
|
|
10259
|
-
|
|
10260
|
-
|
|
10261
|
-
|
|
10262
|
-
|
|
10263
|
-
|
|
10264
|
-
|
|
11138
|
+
},
|
|
11139
|
+
update(id, data) {
|
|
11140
|
+
const index = registry.getIndex(id);
|
|
11141
|
+
if (index === -1)
|
|
11142
|
+
return false;
|
|
11143
|
+
for (const key of Object.keys(data)) {
|
|
11144
|
+
columns.set(key, index, data[key]);
|
|
11145
|
+
}
|
|
11146
|
+
const updatedArr = metadata.updated.value;
|
|
11147
|
+
updatedArr[index] = Date.now();
|
|
11148
|
+
metadata.updated.value = updatedArr;
|
|
11149
|
+
return true;
|
|
11150
|
+
},
|
|
11151
|
+
updateField(id, field, value) {
|
|
11152
|
+
const index = registry.getIndex(id);
|
|
11153
|
+
if (index === -1)
|
|
11154
|
+
return false;
|
|
11155
|
+
columns.set(field, index, value);
|
|
11156
|
+
const updatedArr = metadata.updated.value;
|
|
11157
|
+
updatedArr[index] = Date.now();
|
|
11158
|
+
metadata.updated.value = updatedArr;
|
|
11159
|
+
return true;
|
|
11160
|
+
},
|
|
11161
|
+
updateMany(filter, data) {
|
|
11162
|
+
let count = 0;
|
|
11163
|
+
const indices = registry.getAllIndices();
|
|
11164
|
+
const now = Date.now();
|
|
11165
|
+
for (const index of indices) {
|
|
11166
|
+
const record = columns.getRecord(index);
|
|
11167
|
+
if (filter(record, index)) {
|
|
11168
|
+
for (const key of Object.keys(data)) {
|
|
11169
|
+
columns.set(key, index, data[key]);
|
|
11170
|
+
}
|
|
11171
|
+
const updatedArr = metadata.updated.value;
|
|
11172
|
+
updatedArr[index] = now;
|
|
11173
|
+
metadata.updated.value = updatedArr;
|
|
11174
|
+
count++;
|
|
10265
11175
|
}
|
|
10266
|
-
break;
|
|
10267
11176
|
}
|
|
10268
|
-
|
|
10269
|
-
|
|
10270
|
-
|
|
10271
|
-
|
|
11177
|
+
return count;
|
|
11178
|
+
},
|
|
11179
|
+
delete(id) {
|
|
11180
|
+
const index = registry.getIndex(id);
|
|
11181
|
+
if (index === -1)
|
|
11182
|
+
return false;
|
|
11183
|
+
columns.clearAt(index);
|
|
11184
|
+
const createdArr = metadata.created.value;
|
|
11185
|
+
const updatedArr = metadata.updated.value;
|
|
11186
|
+
const staleArr = metadata.stale.value;
|
|
11187
|
+
if (index < createdArr.length)
|
|
11188
|
+
createdArr[index] = 0;
|
|
11189
|
+
if (index < updatedArr.length)
|
|
11190
|
+
updatedArr[index] = 0;
|
|
11191
|
+
if (index < staleArr.length)
|
|
11192
|
+
staleArr[index] = false;
|
|
11193
|
+
metadata.created.value = createdArr;
|
|
11194
|
+
metadata.updated.value = updatedArr;
|
|
11195
|
+
metadata.stale.value = staleArr;
|
|
11196
|
+
registry.release(id);
|
|
11197
|
+
return true;
|
|
11198
|
+
},
|
|
11199
|
+
deleteMany(filter) {
|
|
11200
|
+
const toDelete = [];
|
|
11201
|
+
const indices = registry.getAllIndices();
|
|
11202
|
+
for (const index of indices) {
|
|
11203
|
+
const data = columns.getRecord(index);
|
|
11204
|
+
if (filter(data, index)) {
|
|
11205
|
+
const id = registry.getId(index);
|
|
11206
|
+
if (id)
|
|
11207
|
+
toDelete.push(id);
|
|
11208
|
+
}
|
|
11209
|
+
}
|
|
11210
|
+
for (const id of toDelete) {
|
|
11211
|
+
collection.delete(id);
|
|
11212
|
+
}
|
|
11213
|
+
return toDelete.length;
|
|
11214
|
+
},
|
|
11215
|
+
count(filter) {
|
|
11216
|
+
if (!filter) {
|
|
11217
|
+
return registry.count;
|
|
10272
11218
|
}
|
|
10273
|
-
|
|
11219
|
+
let count = 0;
|
|
11220
|
+
const indices = registry.getAllIndices();
|
|
11221
|
+
for (const index of indices) {
|
|
11222
|
+
const data = columns.getRecord(index);
|
|
11223
|
+
if (filter(data, index))
|
|
11224
|
+
count++;
|
|
11225
|
+
}
|
|
11226
|
+
return count;
|
|
11227
|
+
},
|
|
11228
|
+
reactiveCount: derived(() => registry.count),
|
|
11229
|
+
getByIndex(index) {
|
|
11230
|
+
if (!registry.allocatedIndices.has(index))
|
|
11231
|
+
return;
|
|
11232
|
+
return buildRecord(index);
|
|
11233
|
+
},
|
|
11234
|
+
getIndices() {
|
|
11235
|
+
return registry.getAllIndices();
|
|
11236
|
+
},
|
|
11237
|
+
has(id) {
|
|
11238
|
+
return registry.has(id);
|
|
11239
|
+
},
|
|
11240
|
+
isStale(id) {
|
|
11241
|
+
const index = registry.getIndex(id);
|
|
11242
|
+
if (index === -1)
|
|
11243
|
+
return false;
|
|
11244
|
+
return metadata.stale.value[index] ?? false;
|
|
11245
|
+
},
|
|
11246
|
+
getStaleIds() {
|
|
11247
|
+
const ids = [];
|
|
11248
|
+
const staleArr = metadata.stale.value;
|
|
11249
|
+
for (const index of registry.getAllIndices()) {
|
|
11250
|
+
if (staleArr[index]) {
|
|
11251
|
+
const id = registry.getId(index);
|
|
11252
|
+
if (id)
|
|
11253
|
+
ids.push(id);
|
|
11254
|
+
}
|
|
11255
|
+
}
|
|
11256
|
+
return ids;
|
|
11257
|
+
},
|
|
11258
|
+
setStale(id, stale) {
|
|
11259
|
+
const index = registry.getIndex(id);
|
|
11260
|
+
if (index === -1)
|
|
11261
|
+
return;
|
|
11262
|
+
const staleArr = metadata.stale.value;
|
|
11263
|
+
while (staleArr.length <= index)
|
|
11264
|
+
staleArr.push(false);
|
|
11265
|
+
staleArr[index] = stale;
|
|
11266
|
+
metadata.stale.value = staleArr;
|
|
11267
|
+
},
|
|
11268
|
+
setMetadata(id, created, updated, stale = false) {
|
|
11269
|
+
const index = registry.getIndex(id);
|
|
11270
|
+
if (index === -1)
|
|
11271
|
+
return;
|
|
11272
|
+
setMetadataAt(index, created, updated, stale);
|
|
11273
|
+
},
|
|
11274
|
+
clear() {
|
|
11275
|
+
registry.reset();
|
|
11276
|
+
columns.reset();
|
|
11277
|
+
metadata.created.value = [];
|
|
11278
|
+
metadata.updated.value = [];
|
|
11279
|
+
metadata.stale.value = [];
|
|
10274
11280
|
}
|
|
11281
|
+
};
|
|
11282
|
+
return collection;
|
|
11283
|
+
}
|
|
11284
|
+
function idToFilename(id) {
|
|
11285
|
+
return id.replace(/[<>:"/\\|?*\x00-\x1f]/g, "_") + ".md";
|
|
11286
|
+
}
|
|
11287
|
+
function filenameToId(filename) {
|
|
11288
|
+
return filename.replace(/\.md$/, "");
|
|
11289
|
+
}
|
|
11290
|
+
function parseMarkdown(text) {
|
|
11291
|
+
const frontmatter = {};
|
|
11292
|
+
let content = "";
|
|
11293
|
+
if (!text.startsWith("---")) {
|
|
11294
|
+
return { frontmatter, content: text.trim() };
|
|
10275
11295
|
}
|
|
10276
|
-
|
|
10277
|
-
|
|
10278
|
-
|
|
10279
|
-
|
|
10280
|
-
return this._indexes.has(column);
|
|
11296
|
+
const endIndex = text.indexOf(`
|
|
11297
|
+
---`, 3);
|
|
11298
|
+
if (endIndex === -1) {
|
|
11299
|
+
return { frontmatter, content: text.trim() };
|
|
10281
11300
|
}
|
|
10282
|
-
|
|
10283
|
-
|
|
10284
|
-
const result = {};
|
|
10285
|
-
const lines = text.split(`
|
|
11301
|
+
const yamlText = text.slice(4, endIndex);
|
|
11302
|
+
const lines = yamlText.split(`
|
|
10286
11303
|
`);
|
|
10287
11304
|
for (const line of lines) {
|
|
10288
11305
|
const trimmed = line.trim();
|
|
10289
|
-
if (!trimmed || trimmed
|
|
11306
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
10290
11307
|
continue;
|
|
10291
11308
|
const colonIndex = trimmed.indexOf(":");
|
|
10292
11309
|
if (colonIndex === -1)
|
|
10293
11310
|
continue;
|
|
10294
11311
|
const key = trimmed.slice(0, colonIndex).trim();
|
|
10295
11312
|
let value = trimmed.slice(colonIndex + 1).trim();
|
|
10296
|
-
|
|
11313
|
+
frontmatter[key] = parseYamlValue(value);
|
|
10297
11314
|
}
|
|
10298
|
-
|
|
11315
|
+
content = text.slice(endIndex + 4).trim();
|
|
11316
|
+
return { frontmatter, content };
|
|
10299
11317
|
}
|
|
10300
|
-
function
|
|
10301
|
-
if (
|
|
10302
|
-
return
|
|
11318
|
+
function parseYamlValue(value) {
|
|
11319
|
+
if (value === "null" || value === "~" || value === "") {
|
|
11320
|
+
return null;
|
|
11321
|
+
}
|
|
10303
11322
|
if (value === "true")
|
|
10304
11323
|
return true;
|
|
10305
11324
|
if (value === "false")
|
|
10306
11325
|
return false;
|
|
11326
|
+
if (/^-?\d+$/.test(value)) {
|
|
11327
|
+
return parseInt(value, 10);
|
|
11328
|
+
}
|
|
11329
|
+
if (/^-?\d+\.\d+$/.test(value)) {
|
|
11330
|
+
return parseFloat(value);
|
|
11331
|
+
}
|
|
10307
11332
|
if (value.startsWith("[") && value.endsWith("]")) {
|
|
10308
|
-
|
|
10309
|
-
|
|
10310
|
-
|
|
10311
|
-
|
|
10312
|
-
const firstItem = items[0];
|
|
10313
|
-
if (firstItem && !isNaN(Number(firstItem))) {
|
|
10314
|
-
return items.map((s) => Number(s));
|
|
11333
|
+
try {
|
|
11334
|
+
return JSON.parse(value);
|
|
11335
|
+
} catch {
|
|
11336
|
+
return value;
|
|
10315
11337
|
}
|
|
10316
|
-
return items.map((s) => s.replace(/^["']|["']$/g, ""));
|
|
10317
11338
|
}
|
|
10318
|
-
if (
|
|
10319
|
-
return
|
|
11339
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
11340
|
+
return value.slice(1, -1);
|
|
10320
11341
|
}
|
|
10321
|
-
return value
|
|
11342
|
+
return value;
|
|
10322
11343
|
}
|
|
10323
|
-
function
|
|
10324
|
-
if (value ===
|
|
10325
|
-
return "";
|
|
10326
|
-
if (value instanceof Float32Array) {
|
|
10327
|
-
return `[${Array.from(value).join(", ")}]`;
|
|
10328
|
-
}
|
|
10329
|
-
if (Array.isArray(value)) {
|
|
10330
|
-
if (value.length === 0)
|
|
10331
|
-
return "[]";
|
|
10332
|
-
if (typeof value[0] === "number") {
|
|
10333
|
-
return `[${value.join(", ")}]`;
|
|
10334
|
-
}
|
|
10335
|
-
return `[${value.map((v) => `"${v}"`).join(", ")}]`;
|
|
11344
|
+
function toYamlValue(value) {
|
|
11345
|
+
if (value === null || value === undefined) {
|
|
11346
|
+
return "null";
|
|
10336
11347
|
}
|
|
10337
11348
|
if (typeof value === "boolean") {
|
|
10338
11349
|
return value ? "true" : "false";
|
|
@@ -10340,746 +11351,618 @@ function serializeValue(value, type) {
|
|
|
10340
11351
|
if (typeof value === "number") {
|
|
10341
11352
|
return String(value);
|
|
10342
11353
|
}
|
|
10343
|
-
|
|
11354
|
+
if (Array.isArray(value)) {
|
|
11355
|
+
return JSON.stringify(value);
|
|
11356
|
+
}
|
|
11357
|
+
if (value instanceof Float32Array) {
|
|
11358
|
+
return JSON.stringify(Array.from(value));
|
|
11359
|
+
}
|
|
11360
|
+
if (typeof value === "string") {
|
|
11361
|
+
if (value.includes(":") || value.includes("#") || value.includes(`
|
|
11362
|
+
`) || value.startsWith('"') || value.startsWith("'") || value === "true" || value === "false" || value === "null") {
|
|
11363
|
+
return JSON.stringify(value);
|
|
11364
|
+
}
|
|
11365
|
+
return value;
|
|
11366
|
+
}
|
|
11367
|
+
return JSON.stringify(value);
|
|
10344
11368
|
}
|
|
10345
|
-
function
|
|
11369
|
+
function generateMarkdown(record, schema, contentColumn) {
|
|
10346
11370
|
const lines = ["---"];
|
|
10347
|
-
|
|
10348
|
-
|
|
11371
|
+
lines.push(`id: ${toYamlValue(record.id)}`);
|
|
11372
|
+
lines.push(`created: ${record.created}`);
|
|
11373
|
+
lines.push(`updated: ${record.updated}`);
|
|
11374
|
+
for (const key of Object.keys(schema)) {
|
|
11375
|
+
if (key === contentColumn)
|
|
10349
11376
|
continue;
|
|
10350
|
-
const
|
|
10351
|
-
lines.push(`${key}: ${
|
|
11377
|
+
const value = record[key];
|
|
11378
|
+
lines.push(`${String(key)}: ${toYamlValue(value)}`);
|
|
10352
11379
|
}
|
|
10353
11380
|
lines.push("---");
|
|
10354
|
-
|
|
10355
|
-
|
|
10356
|
-
|
|
10357
|
-
|
|
10358
|
-
|
|
10359
|
-
`);
|
|
10360
|
-
let inFrontmatter = false;
|
|
10361
|
-
let frontmatterStart = -1;
|
|
10362
|
-
let frontmatterEnd = -1;
|
|
10363
|
-
for (let i = 0;i < lines.length; i++) {
|
|
10364
|
-
const line = lines[i].trim();
|
|
10365
|
-
if (line === "---") {
|
|
10366
|
-
if (!inFrontmatter) {
|
|
10367
|
-
inFrontmatter = true;
|
|
10368
|
-
frontmatterStart = i;
|
|
10369
|
-
} else {
|
|
10370
|
-
frontmatterEnd = i;
|
|
10371
|
-
break;
|
|
10372
|
-
}
|
|
11381
|
+
lines.push("");
|
|
11382
|
+
if (contentColumn) {
|
|
11383
|
+
const content = record[contentColumn];
|
|
11384
|
+
if (typeof content === "string") {
|
|
11385
|
+
lines.push(content);
|
|
10373
11386
|
}
|
|
10374
11387
|
}
|
|
10375
|
-
|
|
10376
|
-
return {
|
|
10377
|
-
id: "",
|
|
10378
|
-
frontmatter: {},
|
|
10379
|
-
content: content.trim()
|
|
10380
|
-
};
|
|
10381
|
-
}
|
|
10382
|
-
const frontmatterText = lines.slice(frontmatterStart + 1, frontmatterEnd).join(`
|
|
11388
|
+
return lines.join(`
|
|
10383
11389
|
`);
|
|
10384
|
-
const frontmatter = parseFrontmatter(frontmatterText);
|
|
10385
|
-
const contentLines = lines.slice(frontmatterEnd + 1);
|
|
10386
|
-
const contentText = contentLines.join(`
|
|
10387
|
-
`).trim();
|
|
10388
|
-
return {
|
|
10389
|
-
id: frontmatter.id || "",
|
|
10390
|
-
frontmatter,
|
|
10391
|
-
content: contentText
|
|
10392
|
-
};
|
|
10393
|
-
}
|
|
10394
|
-
function generateMarkdown(record, content, schema) {
|
|
10395
|
-
const frontmatter = generateFrontmatter(record, schema);
|
|
10396
|
-
return `${frontmatter}
|
|
10397
|
-
|
|
10398
|
-
${content}`;
|
|
10399
|
-
}
|
|
10400
|
-
async function loadFromMarkdown(filePath) {
|
|
10401
|
-
const content = await Bun.file(filePath).text();
|
|
10402
|
-
return parseMarkdown(content);
|
|
10403
|
-
}
|
|
10404
|
-
async function saveToMarkdown(filePath, record, content, schema) {
|
|
10405
|
-
const markdown = generateMarkdown(record, content, schema);
|
|
10406
|
-
await Bun.write(filePath, markdown);
|
|
10407
|
-
}
|
|
10408
|
-
async function loadFromDirectory(dirPath) {
|
|
10409
|
-
const glob = new Bun.Glob("**/*.md");
|
|
10410
|
-
const documents = [];
|
|
10411
|
-
for await (const file of glob.scan({ cwd: dirPath, absolute: true })) {
|
|
10412
|
-
try {
|
|
10413
|
-
const doc = await loadFromMarkdown(file);
|
|
10414
|
-
documents.push(doc);
|
|
10415
|
-
} catch (error) {
|
|
10416
|
-
console.error(`Failed to load ${file}:`, error);
|
|
10417
|
-
}
|
|
10418
|
-
}
|
|
10419
|
-
return documents;
|
|
10420
|
-
}
|
|
10421
|
-
function idToFilename(id) {
|
|
10422
|
-
return id.replace(/[^a-zA-Z0-9-_]/g, "_") + ".md";
|
|
10423
|
-
}
|
|
10424
|
-
function filenameToId(filename) {
|
|
10425
|
-
return filename.replace(/\.md$/, "");
|
|
10426
11390
|
}
|
|
10427
|
-
|
|
10428
|
-
|
|
10429
|
-
_path;
|
|
10430
|
-
_watcher = null;
|
|
10431
|
-
_handler;
|
|
10432
|
-
_options;
|
|
10433
|
-
_debounceTimers = new Map;
|
|
10434
|
-
_knownFiles = new Set;
|
|
10435
|
-
_isStarting = false;
|
|
10436
|
-
constructor(path, handler, options = {}) {
|
|
10437
|
-
this._path = path;
|
|
10438
|
-
this._handler = handler;
|
|
10439
|
-
this._options = {
|
|
10440
|
-
debounceMs: options.debounceMs ?? 100,
|
|
10441
|
-
extension: options.extension ?? ".md"
|
|
10442
|
-
};
|
|
10443
|
-
}
|
|
10444
|
-
async start() {
|
|
10445
|
-
if (this._watcher || this._isStarting)
|
|
10446
|
-
return;
|
|
10447
|
-
this._isStarting = true;
|
|
10448
|
-
await this._scanExistingFiles();
|
|
10449
|
-
this._watcher = watch(this._path, { recursive: false }, (eventType, filename) => {
|
|
10450
|
-
if (!filename)
|
|
10451
|
-
return;
|
|
10452
|
-
if (!filename.endsWith(this._options.extension))
|
|
10453
|
-
return;
|
|
10454
|
-
this._handleChange(eventType, filename);
|
|
10455
|
-
});
|
|
10456
|
-
this._isStarting = false;
|
|
10457
|
-
}
|
|
10458
|
-
stop() {
|
|
10459
|
-
if (this._watcher) {
|
|
10460
|
-
this._watcher.close();
|
|
10461
|
-
this._watcher = null;
|
|
10462
|
-
}
|
|
10463
|
-
for (const timer of this._debounceTimers.values()) {
|
|
10464
|
-
clearTimeout(timer);
|
|
10465
|
-
}
|
|
10466
|
-
this._debounceTimers.clear();
|
|
10467
|
-
}
|
|
10468
|
-
get isWatching() {
|
|
10469
|
-
return this._watcher !== null;
|
|
10470
|
-
}
|
|
10471
|
-
async _scanExistingFiles() {
|
|
10472
|
-
try {
|
|
10473
|
-
const glob = new Bun.Glob(`*${this._options.extension}`);
|
|
10474
|
-
for await (const file of glob.scan({ cwd: this._path, absolute: false })) {
|
|
10475
|
-
this._knownFiles.add(file);
|
|
10476
|
-
}
|
|
10477
|
-
} catch (error) {
|
|
10478
|
-
console.warn(`FileWatcher: Could not scan ${this._path}:`, error);
|
|
10479
|
-
}
|
|
10480
|
-
}
|
|
10481
|
-
_handleChange(eventType, filename) {
|
|
10482
|
-
const existingTimer = this._debounceTimers.get(filename);
|
|
10483
|
-
if (existingTimer) {
|
|
10484
|
-
clearTimeout(existingTimer);
|
|
10485
|
-
}
|
|
10486
|
-
const timer = setTimeout(async () => {
|
|
10487
|
-
this._debounceTimers.delete(filename);
|
|
10488
|
-
await this._processChange(filename);
|
|
10489
|
-
}, this._options.debounceMs);
|
|
10490
|
-
this._debounceTimers.set(filename, timer);
|
|
10491
|
-
}
|
|
10492
|
-
async _processChange(filename) {
|
|
10493
|
-
const filepath = join(this._path, filename);
|
|
10494
|
-
const id = filenameToId(filename);
|
|
11391
|
+
async function loadFromMarkdown(filepath, schema, contentColumn) {
|
|
11392
|
+
try {
|
|
10495
11393
|
const file = Bun.file(filepath);
|
|
10496
|
-
|
|
10497
|
-
|
|
10498
|
-
if (!exists) {
|
|
10499
|
-
if (this._knownFiles.has(filename)) {
|
|
10500
|
-
changeType = "delete";
|
|
10501
|
-
this._knownFiles.delete(filename);
|
|
10502
|
-
} else {
|
|
10503
|
-
return;
|
|
10504
|
-
}
|
|
10505
|
-
} else if (this._knownFiles.has(filename)) {
|
|
10506
|
-
changeType = "update";
|
|
10507
|
-
} else {
|
|
10508
|
-
changeType = "create";
|
|
10509
|
-
this._knownFiles.add(filename);
|
|
11394
|
+
if (!await file.exists()) {
|
|
11395
|
+
return null;
|
|
10510
11396
|
}
|
|
10511
|
-
|
|
10512
|
-
|
|
10513
|
-
|
|
10514
|
-
|
|
10515
|
-
|
|
10516
|
-
|
|
10517
|
-
});
|
|
10518
|
-
} catch (error) {
|
|
10519
|
-
console.error(`FileWatcher: Error handling ${changeType} for ${filename}:`, error);
|
|
10520
|
-
}
|
|
10521
|
-
}
|
|
10522
|
-
async rescan() {
|
|
10523
|
-
const previousFiles = new Set(this._knownFiles);
|
|
10524
|
-
this._knownFiles.clear();
|
|
10525
|
-
await this._scanExistingFiles();
|
|
10526
|
-
for (const filename of this._knownFiles) {
|
|
10527
|
-
if (!previousFiles.has(filename)) {
|
|
10528
|
-
const filepath = join(this._path, filename);
|
|
10529
|
-
const id = filenameToId(filename);
|
|
10530
|
-
await this._handler({
|
|
10531
|
-
type: "create",
|
|
10532
|
-
id,
|
|
10533
|
-
filename,
|
|
10534
|
-
filepath
|
|
10535
|
-
});
|
|
10536
|
-
}
|
|
11397
|
+
const text = await file.text();
|
|
11398
|
+
const { frontmatter, content } = parseMarkdown(text);
|
|
11399
|
+
const id = frontmatter.id;
|
|
11400
|
+
if (!id) {
|
|
11401
|
+
const filename = filepath.split("/").pop() || "";
|
|
11402
|
+
return null;
|
|
10537
11403
|
}
|
|
10538
|
-
|
|
10539
|
-
|
|
10540
|
-
|
|
10541
|
-
|
|
10542
|
-
|
|
10543
|
-
|
|
10544
|
-
|
|
10545
|
-
|
|
10546
|
-
|
|
10547
|
-
|
|
11404
|
+
const record = {
|
|
11405
|
+
id,
|
|
11406
|
+
created: frontmatter.created || Date.now(),
|
|
11407
|
+
updated: frontmatter.updated || Date.now(),
|
|
11408
|
+
stale: false
|
|
11409
|
+
};
|
|
11410
|
+
for (const key of Object.keys(schema)) {
|
|
11411
|
+
if (key === contentColumn) {
|
|
11412
|
+
record[key] = content;
|
|
11413
|
+
} else if (key in frontmatter) {
|
|
11414
|
+
let value = frontmatter[key];
|
|
11415
|
+
const parsed = parseColumnType(schema[key]);
|
|
11416
|
+
if (parsed.baseType === "vector" && Array.isArray(value)) {
|
|
11417
|
+
value = new Float32Array(value);
|
|
11418
|
+
}
|
|
11419
|
+
record[key] = value;
|
|
10548
11420
|
}
|
|
10549
11421
|
}
|
|
11422
|
+
return { id, record };
|
|
11423
|
+
} catch {
|
|
11424
|
+
return null;
|
|
10550
11425
|
}
|
|
10551
11426
|
}
|
|
10552
|
-
function
|
|
10553
|
-
|
|
10554
|
-
|
|
11427
|
+
async function saveToMarkdown(filepath, record, schema, contentColumn) {
|
|
11428
|
+
try {
|
|
11429
|
+
const markdown = generateMarkdown(record, schema, contentColumn);
|
|
11430
|
+
await Bun.write(filepath, markdown);
|
|
11431
|
+
return true;
|
|
11432
|
+
} catch {
|
|
11433
|
+
return false;
|
|
10555
11434
|
}
|
|
10556
|
-
let dotProduct = 0;
|
|
10557
|
-
let normA = 0;
|
|
10558
|
-
let normB = 0;
|
|
10559
|
-
for (let i = 0;i < a.length; i++) {
|
|
10560
|
-
const ai = a[i];
|
|
10561
|
-
const bi = b[i];
|
|
10562
|
-
dotProduct += ai * bi;
|
|
10563
|
-
normA += ai * ai;
|
|
10564
|
-
normB += bi * bi;
|
|
10565
|
-
}
|
|
10566
|
-
const magnitude = Math.sqrt(normA) * Math.sqrt(normB);
|
|
10567
|
-
if (magnitude === 0)
|
|
10568
|
-
return 0;
|
|
10569
|
-
return dotProduct / magnitude;
|
|
10570
11435
|
}
|
|
10571
|
-
function
|
|
11436
|
+
async function loadFromDirectory(dirpath, schema, contentColumn) {
|
|
10572
11437
|
const results = [];
|
|
10573
|
-
|
|
10574
|
-
|
|
10575
|
-
|
|
10576
|
-
|
|
10577
|
-
|
|
10578
|
-
|
|
10579
|
-
|
|
10580
|
-
|
|
10581
|
-
const vector = vectors[idx];
|
|
10582
|
-
if (!vector)
|
|
10583
|
-
continue;
|
|
10584
|
-
let dotProduct = 0;
|
|
10585
|
-
let vectorNorm = 0;
|
|
10586
|
-
for (let i = 0;i < query.length; i++) {
|
|
10587
|
-
const vi = vector[i];
|
|
10588
|
-
dotProduct += query[i] * vi;
|
|
10589
|
-
vectorNorm += vi * vi;
|
|
10590
|
-
}
|
|
10591
|
-
vectorNorm = Math.sqrt(vectorNorm);
|
|
10592
|
-
if (vectorNorm === 0)
|
|
10593
|
-
continue;
|
|
10594
|
-
const similarity = dotProduct / (queryNorm * vectorNorm);
|
|
10595
|
-
results.push({ index: idx, similarity });
|
|
10596
|
-
}
|
|
10597
|
-
results.sort((a, b) => b.similarity - a.similarity);
|
|
10598
|
-
if (topK !== undefined && topK > 0) {
|
|
10599
|
-
return results.slice(0, topK);
|
|
10600
|
-
}
|
|
10601
|
-
return results;
|
|
10602
|
-
}
|
|
10603
|
-
function vectorSearch(vectors, indices, query, options = {}) {
|
|
10604
|
-
const { topK, minSimilarity = 0 } = options;
|
|
10605
|
-
let results = batchCosineSimilarity(query, vectors, indices, topK);
|
|
10606
|
-
if (minSimilarity > 0) {
|
|
10607
|
-
results = results.filter((r) => r.similarity >= minSimilarity);
|
|
10608
|
-
}
|
|
10609
|
-
return results;
|
|
10610
|
-
}
|
|
10611
|
-
function toFloat32Array(arr) {
|
|
10612
|
-
return new Float32Array(arr);
|
|
10613
|
-
}
|
|
10614
|
-
|
|
10615
|
-
class Database {
|
|
10616
|
-
_options;
|
|
10617
|
-
_columns;
|
|
10618
|
-
_schema;
|
|
10619
|
-
_contentColumn;
|
|
10620
|
-
_watcher = null;
|
|
10621
|
-
_isSaving = new Set;
|
|
10622
|
-
_created = [];
|
|
10623
|
-
_updated = [];
|
|
10624
|
-
_contentHashes = new ReactiveMap;
|
|
10625
|
-
_staleFlags = [];
|
|
10626
|
-
_onFileChange;
|
|
10627
|
-
constructor(options) {
|
|
10628
|
-
this._options = options;
|
|
10629
|
-
this._schema = createSchema(options.schema);
|
|
10630
|
-
this._columns = new Columns(options.schema);
|
|
10631
|
-
this._contentColumn = options.contentColumn;
|
|
10632
|
-
}
|
|
10633
|
-
onFileChange(callback) {
|
|
10634
|
-
this._onFileChange = callback;
|
|
10635
|
-
}
|
|
10636
|
-
setEmbedding(id, vectorColumn, embedding, sourceContent) {
|
|
10637
|
-
const index = getIndex(id);
|
|
10638
|
-
if (index === undefined)
|
|
10639
|
-
return false;
|
|
10640
|
-
const vector = Array.isArray(embedding) ? toFloat32Array(embedding) : embedding;
|
|
10641
|
-
this._columns.set(vectorColumn, index, vector);
|
|
10642
|
-
if (!this._contentHashes.has(vectorColumn)) {
|
|
10643
|
-
this._contentHashes.set(vectorColumn, []);
|
|
10644
|
-
}
|
|
10645
|
-
this._contentHashes.get(vectorColumn)[index] = Bun.hash(sourceContent);
|
|
10646
|
-
this._staleFlags[index] = false;
|
|
10647
|
-
return true;
|
|
10648
|
-
}
|
|
10649
|
-
isStale(id) {
|
|
10650
|
-
const index = getIndex(id);
|
|
10651
|
-
if (index === undefined)
|
|
10652
|
-
return false;
|
|
10653
|
-
return this._staleFlags[index] ?? false;
|
|
10654
|
-
}
|
|
10655
|
-
setStale(id, stale) {
|
|
10656
|
-
const index = getIndex(id);
|
|
10657
|
-
if (index === undefined)
|
|
10658
|
-
return;
|
|
10659
|
-
this._staleFlags[index] = stale;
|
|
10660
|
-
}
|
|
10661
|
-
getStaleIds() {
|
|
10662
|
-
const staleIds = [];
|
|
10663
|
-
for (const index of getAllIndices()) {
|
|
10664
|
-
if (this._staleFlags[index]) {
|
|
10665
|
-
const id = getId(index);
|
|
10666
|
-
if (id)
|
|
10667
|
-
staleIds.push(id);
|
|
10668
|
-
}
|
|
10669
|
-
}
|
|
10670
|
-
return staleIds;
|
|
10671
|
-
}
|
|
10672
|
-
async insert(data) {
|
|
10673
|
-
const id = data.id || this._generateId();
|
|
10674
|
-
const index = allocateIndex(id);
|
|
10675
|
-
const now = Date.now();
|
|
10676
|
-
this._created[index] = now;
|
|
10677
|
-
this._updated[index] = now;
|
|
10678
|
-
for (const [key, value] of Object.entries(data)) {
|
|
10679
|
-
if (key === "id")
|
|
10680
|
-
continue;
|
|
10681
|
-
const colType = this._options.schema[key];
|
|
10682
|
-
if (colType && typeof colType === "string" && colType.startsWith("vector:")) {
|
|
10683
|
-
if (Array.isArray(value)) {
|
|
10684
|
-
this._columns.set(key, index, toFloat32Array(value));
|
|
10685
|
-
} else {
|
|
10686
|
-
this._columns.set(key, index, value);
|
|
10687
|
-
}
|
|
10688
|
-
} else {
|
|
10689
|
-
this._columns.set(key, index, value);
|
|
10690
|
-
}
|
|
10691
|
-
}
|
|
10692
|
-
if (this._options.autoSave && this._options.path) {
|
|
10693
|
-
await this._saveRecord(id, index);
|
|
10694
|
-
}
|
|
10695
|
-
return id;
|
|
10696
|
-
}
|
|
10697
|
-
get(id) {
|
|
10698
|
-
const index = getIndex(id);
|
|
10699
|
-
if (index === undefined)
|
|
10700
|
-
return null;
|
|
10701
|
-
const record = this._columns.getRecord(index);
|
|
10702
|
-
return {
|
|
10703
|
-
id,
|
|
10704
|
-
...record,
|
|
10705
|
-
created: this._created[index] || 0,
|
|
10706
|
-
updated: this._updated[index] || 0,
|
|
10707
|
-
stale: this._staleFlags[index] ?? false
|
|
10708
|
-
};
|
|
10709
|
-
}
|
|
10710
|
-
async update(id, data) {
|
|
10711
|
-
const index = getIndex(id);
|
|
10712
|
-
if (index === undefined)
|
|
10713
|
-
return false;
|
|
10714
|
-
this._updated[index] = Date.now();
|
|
10715
|
-
for (const [key, value] of Object.entries(data)) {
|
|
10716
|
-
const colType = this._options.schema[key];
|
|
10717
|
-
if (colType && typeof colType === "string" && colType.startsWith("vector:")) {
|
|
10718
|
-
if (Array.isArray(value)) {
|
|
10719
|
-
this._columns.set(key, index, toFloat32Array(value));
|
|
10720
|
-
} else {
|
|
10721
|
-
this._columns.set(key, index, value);
|
|
10722
|
-
}
|
|
10723
|
-
} else {
|
|
10724
|
-
this._columns.set(key, index, value);
|
|
11438
|
+
try {
|
|
11439
|
+
const glob = new Bun.Glob("*.md");
|
|
11440
|
+
const files = glob.scanSync({ cwd: dirpath });
|
|
11441
|
+
for (const filename of files) {
|
|
11442
|
+
const filepath = `${dirpath}/${filename}`;
|
|
11443
|
+
const result = await loadFromMarkdown(filepath, schema, contentColumn);
|
|
11444
|
+
if (result) {
|
|
11445
|
+
results.push(result);
|
|
10725
11446
|
}
|
|
10726
11447
|
}
|
|
10727
|
-
|
|
10728
|
-
|
|
10729
|
-
|
|
11448
|
+
} catch {}
|
|
11449
|
+
return results;
|
|
11450
|
+
}
|
|
11451
|
+
async function deleteMarkdownFile(filepath) {
|
|
11452
|
+
try {
|
|
11453
|
+
const fs = await import("fs/promises");
|
|
11454
|
+
await fs.unlink(filepath);
|
|
10730
11455
|
return true;
|
|
11456
|
+
} catch {
|
|
11457
|
+
return false;
|
|
10731
11458
|
}
|
|
10732
|
-
|
|
10733
|
-
|
|
10734
|
-
|
|
10735
|
-
|
|
10736
|
-
|
|
10737
|
-
|
|
10738
|
-
|
|
10739
|
-
|
|
10740
|
-
|
|
10741
|
-
|
|
10742
|
-
|
|
10743
|
-
|
|
10744
|
-
|
|
10745
|
-
|
|
11459
|
+
}
|
|
11460
|
+
async function ensureDirectory(dirpath) {
|
|
11461
|
+
const fs = await import("fs/promises");
|
|
11462
|
+
await fs.mkdir(dirpath, { recursive: true });
|
|
11463
|
+
}
|
|
11464
|
+
function createFileWatcher(options) {
|
|
11465
|
+
const {
|
|
11466
|
+
dirpath,
|
|
11467
|
+
schema,
|
|
11468
|
+
contentColumn,
|
|
11469
|
+
debounceMs = WATCHER_DEBOUNCE_MS
|
|
11470
|
+
} = options;
|
|
11471
|
+
const _isWatching = signal(false);
|
|
11472
|
+
const _callbacks = new Set;
|
|
11473
|
+
const _savingIds = new Set;
|
|
11474
|
+
const _knownFiles = new Set;
|
|
11475
|
+
const _pendingChanges = new Map;
|
|
11476
|
+
let _watcher = null;
|
|
11477
|
+
async function processChange(filename) {
|
|
11478
|
+
if (!filename.endsWith(".md"))
|
|
11479
|
+
return;
|
|
11480
|
+
const id = filenameToId(filename);
|
|
11481
|
+
const filepath = `${dirpath}/${filename}`;
|
|
11482
|
+
if (_savingIds.has(id)) {
|
|
11483
|
+
return;
|
|
10746
11484
|
}
|
|
10747
|
-
|
|
10748
|
-
|
|
10749
|
-
|
|
10750
|
-
|
|
10751
|
-
|
|
10752
|
-
|
|
10753
|
-
|
|
10754
|
-
|
|
10755
|
-
|
|
10756
|
-
const withMeta = {
|
|
11485
|
+
const file = Bun.file(filepath);
|
|
11486
|
+
const exists = await file.exists();
|
|
11487
|
+
let event;
|
|
11488
|
+
if (!exists) {
|
|
11489
|
+
if (!_knownFiles.has(filename))
|
|
11490
|
+
return;
|
|
11491
|
+
_knownFiles.delete(filename);
|
|
11492
|
+
event = {
|
|
11493
|
+
type: "delete",
|
|
10757
11494
|
id,
|
|
10758
|
-
|
|
10759
|
-
|
|
10760
|
-
|
|
10761
|
-
stale: this._staleFlags[index] || false
|
|
11495
|
+
filename,
|
|
11496
|
+
filepath,
|
|
11497
|
+
stale: false
|
|
10762
11498
|
};
|
|
10763
|
-
|
|
10764
|
-
|
|
11499
|
+
} else {
|
|
11500
|
+
const isNew = !_knownFiles.has(filename);
|
|
11501
|
+
_knownFiles.add(filename);
|
|
11502
|
+
const result = await loadFromMarkdown(filepath, schema, contentColumn);
|
|
11503
|
+
if (!result)
|
|
11504
|
+
return;
|
|
11505
|
+
let stale = false;
|
|
11506
|
+
if (options.isStaleCallback && contentColumn) {
|
|
11507
|
+
const content = result.record[contentColumn];
|
|
11508
|
+
if (content) {
|
|
11509
|
+
stale = options.isStaleCallback(id, content);
|
|
11510
|
+
}
|
|
10765
11511
|
}
|
|
10766
|
-
|
|
10767
|
-
|
|
10768
|
-
}
|
|
10769
|
-
findOne(filter) {
|
|
10770
|
-
for (const index of getAllIndices()) {
|
|
10771
|
-
const id = getId(index);
|
|
10772
|
-
if (!id)
|
|
10773
|
-
continue;
|
|
10774
|
-
const record = this._columns.getRecord(index);
|
|
10775
|
-
const withMeta = {
|
|
11512
|
+
event = {
|
|
11513
|
+
type: isNew ? "create" : "update",
|
|
10776
11514
|
id,
|
|
10777
|
-
|
|
10778
|
-
|
|
10779
|
-
|
|
10780
|
-
stale
|
|
11515
|
+
filename,
|
|
11516
|
+
filepath,
|
|
11517
|
+
record: result.record,
|
|
11518
|
+
stale
|
|
10781
11519
|
};
|
|
10782
|
-
if (filter(withMeta)) {
|
|
10783
|
-
return withMeta;
|
|
10784
|
-
}
|
|
10785
|
-
}
|
|
10786
|
-
return null;
|
|
10787
|
-
}
|
|
10788
|
-
all() {
|
|
10789
|
-
return this.find(() => true);
|
|
10790
|
-
}
|
|
10791
|
-
count(filter) {
|
|
10792
|
-
if (!filter) {
|
|
10793
|
-
return registry.count;
|
|
10794
|
-
}
|
|
10795
|
-
return this.find(filter).length;
|
|
10796
|
-
}
|
|
10797
|
-
async insertMany(records) {
|
|
10798
|
-
const ids = [];
|
|
10799
|
-
for (const record of records) {
|
|
10800
|
-
const id = await this.insert(record);
|
|
10801
|
-
ids.push(id);
|
|
10802
|
-
}
|
|
10803
|
-
return ids;
|
|
10804
|
-
}
|
|
10805
|
-
async updateMany(filter, data) {
|
|
10806
|
-
const matches = this.find(filter);
|
|
10807
|
-
let count = 0;
|
|
10808
|
-
for (const record of matches) {
|
|
10809
|
-
const success = await this.update(record.id, data);
|
|
10810
|
-
if (success)
|
|
10811
|
-
count++;
|
|
10812
11520
|
}
|
|
10813
|
-
|
|
10814
|
-
|
|
10815
|
-
|
|
10816
|
-
|
|
10817
|
-
|
|
10818
|
-
|
|
10819
|
-
const success = await this.delete(record.id);
|
|
10820
|
-
if (success)
|
|
10821
|
-
count++;
|
|
11521
|
+
for (const callback of _callbacks) {
|
|
11522
|
+
try {
|
|
11523
|
+
await callback(event);
|
|
11524
|
+
} catch (err) {
|
|
11525
|
+
console.error("File watcher callback error:", err);
|
|
11526
|
+
}
|
|
10822
11527
|
}
|
|
10823
|
-
return count;
|
|
10824
11528
|
}
|
|
10825
|
-
|
|
10826
|
-
const
|
|
10827
|
-
|
|
10828
|
-
|
|
10829
|
-
let indices = getAllIndices();
|
|
10830
|
-
if (filter) {
|
|
10831
|
-
indices = indices.filter((idx) => {
|
|
10832
|
-
const id = getId(idx);
|
|
10833
|
-
if (!id)
|
|
10834
|
-
return false;
|
|
10835
|
-
const record = this._columns.getRecord(idx);
|
|
10836
|
-
return filter({ id, ...record });
|
|
10837
|
-
});
|
|
11529
|
+
function handleChange(filename) {
|
|
11530
|
+
const existing = _pendingChanges.get(filename);
|
|
11531
|
+
if (existing) {
|
|
11532
|
+
clearTimeout(existing);
|
|
10838
11533
|
}
|
|
10839
|
-
const
|
|
10840
|
-
|
|
10841
|
-
|
|
10842
|
-
|
|
10843
|
-
|
|
10844
|
-
return { id, ...record, similarity, stale };
|
|
10845
|
-
});
|
|
11534
|
+
const timeout = setTimeout(() => {
|
|
11535
|
+
_pendingChanges.delete(filename);
|
|
11536
|
+
processChange(filename);
|
|
11537
|
+
}, debounceMs);
|
|
11538
|
+
_pendingChanges.set(filename, timeout);
|
|
10846
11539
|
}
|
|
10847
|
-
|
|
10848
|
-
|
|
10849
|
-
|
|
10850
|
-
|
|
10851
|
-
|
|
10852
|
-
|
|
10853
|
-
|
|
10854
|
-
|
|
10855
|
-
continue;
|
|
10856
|
-
const index = allocateIndex(doc.id);
|
|
10857
|
-
for (const [key, value] of Object.entries(doc.frontmatter)) {
|
|
10858
|
-
if (key === "id")
|
|
10859
|
-
continue;
|
|
10860
|
-
if (key === "created") {
|
|
10861
|
-
this._created[index] = value;
|
|
10862
|
-
continue;
|
|
10863
|
-
}
|
|
10864
|
-
if (key === "updated") {
|
|
10865
|
-
this._updated[index] = value;
|
|
10866
|
-
continue;
|
|
11540
|
+
const watcher = {
|
|
11541
|
+
start() {
|
|
11542
|
+
if (_isWatching.value)
|
|
11543
|
+
return;
|
|
11544
|
+
try {
|
|
11545
|
+
const glob = new Bun.Glob("*.md");
|
|
11546
|
+
for (const filename of glob.scanSync({ cwd: dirpath })) {
|
|
11547
|
+
_knownFiles.add(filename);
|
|
10867
11548
|
}
|
|
10868
|
-
|
|
10869
|
-
|
|
10870
|
-
|
|
10871
|
-
this._columns.set(key, index, toFloat32Array(value));
|
|
11549
|
+
_watcher = watch(dirpath, { recursive: false }, (eventType, filename) => {
|
|
11550
|
+
if (filename && filename.endsWith(".md")) {
|
|
11551
|
+
handleChange(filename);
|
|
10872
11552
|
}
|
|
10873
|
-
}
|
|
10874
|
-
|
|
10875
|
-
|
|
11553
|
+
});
|
|
11554
|
+
_isWatching.value = true;
|
|
11555
|
+
} catch (err) {
|
|
11556
|
+
console.error("Failed to start file watcher:", err);
|
|
10876
11557
|
}
|
|
10877
|
-
|
|
10878
|
-
|
|
11558
|
+
},
|
|
11559
|
+
stop() {
|
|
11560
|
+
if (!_isWatching.value)
|
|
11561
|
+
return;
|
|
11562
|
+
for (const timeout of _pendingChanges.values()) {
|
|
11563
|
+
clearTimeout(timeout);
|
|
10879
11564
|
}
|
|
10880
|
-
|
|
10881
|
-
|
|
10882
|
-
|
|
10883
|
-
|
|
10884
|
-
}
|
|
10885
|
-
return count;
|
|
10886
|
-
}
|
|
10887
|
-
_reconcileSchema() {
|
|
10888
|
-
const indices = getAllIndices();
|
|
10889
|
-
if (indices.length === 0)
|
|
10890
|
-
return;
|
|
10891
|
-
for (const [field, type] of Object.entries(this._options.schema)) {
|
|
10892
|
-
const column = this._columns.getColumn(field);
|
|
10893
|
-
const defaultValue = getDefaultForType(type);
|
|
10894
|
-
for (const index of indices) {
|
|
10895
|
-
if (column[index] === undefined) {
|
|
10896
|
-
this._columns.set(field, index, defaultValue);
|
|
10897
|
-
}
|
|
11565
|
+
_pendingChanges.clear();
|
|
11566
|
+
if (_watcher) {
|
|
11567
|
+
_watcher.close();
|
|
11568
|
+
_watcher = null;
|
|
10898
11569
|
}
|
|
11570
|
+
_isWatching.value = false;
|
|
11571
|
+
},
|
|
11572
|
+
get isWatching() {
|
|
11573
|
+
return _isWatching.value;
|
|
11574
|
+
},
|
|
11575
|
+
onChange(callback) {
|
|
11576
|
+
_callbacks.add(callback);
|
|
11577
|
+
return () => _callbacks.delete(callback);
|
|
11578
|
+
},
|
|
11579
|
+
markSaving(id) {
|
|
11580
|
+
_savingIds.add(id);
|
|
11581
|
+
},
|
|
11582
|
+
clearSaving(id) {
|
|
11583
|
+
setTimeout(() => {
|
|
11584
|
+
_savingIds.delete(id);
|
|
11585
|
+
}, SAVE_GRACE_PERIOD_MS);
|
|
10899
11586
|
}
|
|
11587
|
+
};
|
|
11588
|
+
return watcher;
|
|
11589
|
+
}
|
|
11590
|
+
function toFloat32Array(arr) {
|
|
11591
|
+
if (arr instanceof Float32Array)
|
|
11592
|
+
return arr;
|
|
11593
|
+
return new Float32Array(arr);
|
|
11594
|
+
}
|
|
11595
|
+
function cosineSimilarity(a, b) {
|
|
11596
|
+
const vecA = a instanceof Float32Array ? a : new Float32Array(a);
|
|
11597
|
+
const vecB = b instanceof Float32Array ? b : new Float32Array(b);
|
|
11598
|
+
if (vecA.length !== vecB.length) {
|
|
11599
|
+
throw new Error(`Vector dimension mismatch: ${vecA.length} vs ${vecB.length}`);
|
|
10900
11600
|
}
|
|
10901
|
-
|
|
10902
|
-
|
|
10903
|
-
|
|
10904
|
-
|
|
10905
|
-
|
|
10906
|
-
|
|
10907
|
-
|
|
10908
|
-
if (!id)
|
|
10909
|
-
continue;
|
|
10910
|
-
await this._saveRecord(id, index);
|
|
10911
|
-
count++;
|
|
10912
|
-
}
|
|
10913
|
-
return count;
|
|
10914
|
-
}
|
|
10915
|
-
get columns() {
|
|
10916
|
-
return this._columns;
|
|
10917
|
-
}
|
|
10918
|
-
get registry() {
|
|
10919
|
-
return registry;
|
|
10920
|
-
}
|
|
10921
|
-
getColumn(name) {
|
|
10922
|
-
return this._columns.getColumn(name);
|
|
10923
|
-
}
|
|
10924
|
-
createIndex(column) {
|
|
10925
|
-
return this._columns.createIndex(column);
|
|
10926
|
-
}
|
|
10927
|
-
getByIndex(index) {
|
|
10928
|
-
if (!registry.allocatedIndices.has(index))
|
|
10929
|
-
return null;
|
|
10930
|
-
return this._columns.getRecord(index);
|
|
11601
|
+
let dot = 0;
|
|
11602
|
+
let normA = 0;
|
|
11603
|
+
let normB = 0;
|
|
11604
|
+
for (let i = 0;i < vecA.length; i++) {
|
|
11605
|
+
dot += vecA[i] * vecB[i];
|
|
11606
|
+
normA += vecA[i] * vecA[i];
|
|
11607
|
+
normB += vecB[i] * vecB[i];
|
|
10931
11608
|
}
|
|
10932
|
-
|
|
10933
|
-
|
|
11609
|
+
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
11610
|
+
if (denom === 0)
|
|
11611
|
+
return 0;
|
|
11612
|
+
return dot / denom;
|
|
11613
|
+
}
|
|
11614
|
+
function batchCosineSimilarity(query, vectors, indices, topK) {
|
|
11615
|
+
let queryNorm = 0;
|
|
11616
|
+
for (let i = 0;i < query.length; i++) {
|
|
11617
|
+
queryNorm += query[i] * query[i];
|
|
10934
11618
|
}
|
|
10935
|
-
|
|
10936
|
-
|
|
11619
|
+
queryNorm = Math.sqrt(queryNorm);
|
|
11620
|
+
if (queryNorm === 0)
|
|
11621
|
+
return [];
|
|
11622
|
+
const results = [];
|
|
11623
|
+
for (let i = 0;i < vectors.length; i++) {
|
|
11624
|
+
const vec = vectors[i];
|
|
11625
|
+
if (!vec)
|
|
11626
|
+
continue;
|
|
11627
|
+
let dot = 0;
|
|
11628
|
+
let vecNorm = 0;
|
|
11629
|
+
for (let j = 0;j < query.length; j++) {
|
|
11630
|
+
dot += query[j] * vec[j];
|
|
11631
|
+
vecNorm += vec[j] * vec[j];
|
|
11632
|
+
}
|
|
11633
|
+
vecNorm = Math.sqrt(vecNorm);
|
|
11634
|
+
if (vecNorm === 0)
|
|
11635
|
+
continue;
|
|
11636
|
+
const similarity = dot / (queryNorm * vecNorm);
|
|
11637
|
+
results.push({ index: indices[i], similarity });
|
|
10937
11638
|
}
|
|
10938
|
-
|
|
10939
|
-
|
|
10940
|
-
|
|
10941
|
-
|
|
10942
|
-
|
|
10943
|
-
|
|
10944
|
-
|
|
10945
|
-
|
|
10946
|
-
|
|
10947
|
-
|
|
10948
|
-
|
|
10949
|
-
|
|
10950
|
-
|
|
10951
|
-
|
|
10952
|
-
|
|
10953
|
-
|
|
10954
|
-
|
|
10955
|
-
|
|
10956
|
-
|
|
10957
|
-
|
|
11639
|
+
results.sort((a, b) => b.similarity - a.similarity);
|
|
11640
|
+
return results.slice(0, topK);
|
|
11641
|
+
}
|
|
11642
|
+
function createEmbeddingManager() {
|
|
11643
|
+
const hashes = new ReactiveMap;
|
|
11644
|
+
return {
|
|
11645
|
+
setEmbedding(id, column, content) {
|
|
11646
|
+
const hash = BigInt(Bun.hash(content));
|
|
11647
|
+
let columnHashes = hashes.get(id);
|
|
11648
|
+
if (!columnHashes) {
|
|
11649
|
+
columnHashes = new Map;
|
|
11650
|
+
hashes.set(id, columnHashes);
|
|
11651
|
+
}
|
|
11652
|
+
columnHashes.set(column, hash);
|
|
11653
|
+
},
|
|
11654
|
+
isStale(id, column, currentContent) {
|
|
11655
|
+
const columnHashes = hashes.get(id);
|
|
11656
|
+
if (!columnHashes)
|
|
11657
|
+
return false;
|
|
11658
|
+
const storedHash = columnHashes.get(column);
|
|
11659
|
+
if (storedHash === undefined)
|
|
11660
|
+
return false;
|
|
11661
|
+
const currentHash = BigInt(Bun.hash(currentContent));
|
|
11662
|
+
return storedHash !== currentHash;
|
|
11663
|
+
},
|
|
11664
|
+
getHash(id, column) {
|
|
11665
|
+
return hashes.get(id)?.get(column);
|
|
11666
|
+
},
|
|
11667
|
+
clearHash(id, column) {
|
|
11668
|
+
const columnHashes = hashes.get(id);
|
|
11669
|
+
if (columnHashes) {
|
|
11670
|
+
columnHashes.delete(column);
|
|
11671
|
+
if (columnHashes.size === 0) {
|
|
11672
|
+
hashes.delete(id);
|
|
10958
11673
|
}
|
|
10959
11674
|
}
|
|
10960
|
-
|
|
10961
|
-
|
|
10962
|
-
|
|
10963
|
-
} finally {
|
|
10964
|
-
setTimeout(() => {
|
|
10965
|
-
this._isSaving.delete(id);
|
|
10966
|
-
}, 200);
|
|
10967
|
-
}
|
|
10968
|
-
}
|
|
10969
|
-
async startWatching() {
|
|
10970
|
-
if (!this._options.path) {
|
|
10971
|
-
throw new Error("No storage path configured");
|
|
11675
|
+
},
|
|
11676
|
+
reset() {
|
|
11677
|
+
hashes.clear();
|
|
10972
11678
|
}
|
|
10973
|
-
|
|
10974
|
-
|
|
11679
|
+
};
|
|
11680
|
+
}
|
|
11681
|
+
function vectorSearch(collection, vectorColumn, queryVector, options = {}) {
|
|
11682
|
+
const { topK = 10, minSimilarity = 0, filter } = options;
|
|
11683
|
+
const query = toFloat32Array(queryVector);
|
|
11684
|
+
const vectors = [];
|
|
11685
|
+
const vectorIndices = [];
|
|
11686
|
+
for (const index of collection.getIndices()) {
|
|
11687
|
+
if (filter) {
|
|
11688
|
+
const data = collection.columns.getRecord(index);
|
|
11689
|
+
if (!filter(data, index))
|
|
11690
|
+
continue;
|
|
10975
11691
|
}
|
|
10976
|
-
|
|
10977
|
-
|
|
10978
|
-
|
|
10979
|
-
|
|
10980
|
-
if (this._watcher) {
|
|
10981
|
-
this._watcher.stop();
|
|
10982
|
-
this._watcher = null;
|
|
11692
|
+
const vec = collection.columns.get(vectorColumn, index);
|
|
11693
|
+
if (vec) {
|
|
11694
|
+
vectors.push(vec);
|
|
11695
|
+
vectorIndices.push(index);
|
|
10983
11696
|
}
|
|
10984
11697
|
}
|
|
10985
|
-
|
|
10986
|
-
|
|
11698
|
+
const topResults = batchCosineSimilarity(query, vectors, vectorIndices, topK);
|
|
11699
|
+
const results = [];
|
|
11700
|
+
for (const { index, similarity } of topResults) {
|
|
11701
|
+
if (similarity < minSimilarity)
|
|
11702
|
+
continue;
|
|
11703
|
+
const record = collection.getByIndex(index);
|
|
11704
|
+
if (!record)
|
|
11705
|
+
continue;
|
|
11706
|
+
results.push({
|
|
11707
|
+
record,
|
|
11708
|
+
similarity,
|
|
11709
|
+
stale: collection.isStale(record.id)
|
|
11710
|
+
});
|
|
10987
11711
|
}
|
|
10988
|
-
|
|
10989
|
-
|
|
10990
|
-
|
|
10991
|
-
|
|
11712
|
+
return results;
|
|
11713
|
+
}
|
|
11714
|
+
function createPersistentCollection(name, options) {
|
|
11715
|
+
const baseCollection = createCollection(name, options);
|
|
11716
|
+
const { path, schema, contentColumn, autoSave = false, watchFiles = false, onExternalChange } = options;
|
|
11717
|
+
const embeddingManager = createEmbeddingManager();
|
|
11718
|
+
let fileWatcher = null;
|
|
11719
|
+
const savingIds = new Set;
|
|
11720
|
+
function getFilepath(id) {
|
|
11721
|
+
return `${path}/${idToFilename(id)}`;
|
|
11722
|
+
}
|
|
11723
|
+
async function saveRecord(id) {
|
|
11724
|
+
const record = baseCollection.get(id);
|
|
11725
|
+
if (!record)
|
|
11726
|
+
return false;
|
|
11727
|
+
savingIds.add(id);
|
|
11728
|
+
if (fileWatcher)
|
|
11729
|
+
fileWatcher.markSaving(id);
|
|
11730
|
+
const success = await saveToMarkdown(getFilepath(id), record, schema, contentColumn);
|
|
11731
|
+
setTimeout(() => {
|
|
11732
|
+
savingIds.delete(id);
|
|
11733
|
+
if (fileWatcher)
|
|
11734
|
+
fileWatcher.clearSaving(id);
|
|
11735
|
+
}, 200);
|
|
11736
|
+
return success;
|
|
11737
|
+
}
|
|
11738
|
+
async function deleteFile(id) {
|
|
11739
|
+
return await deleteMarkdownFile(getFilepath(id));
|
|
11740
|
+
}
|
|
11741
|
+
function isContentStale(id, content) {
|
|
11742
|
+
for (const col of baseCollection.columns.schema.vectorColumns) {
|
|
11743
|
+
if (embeddingManager.isStale(id, String(col), content)) {
|
|
11744
|
+
return true;
|
|
11745
|
+
}
|
|
10992
11746
|
}
|
|
10993
|
-
|
|
10994
|
-
|
|
10995
|
-
|
|
10996
|
-
|
|
10997
|
-
|
|
10998
|
-
|
|
10999
|
-
|
|
11000
|
-
|
|
11001
|
-
|
|
11002
|
-
|
|
11003
|
-
|
|
11004
|
-
|
|
11005
|
-
|
|
11006
|
-
|
|
11007
|
-
|
|
11008
|
-
|
|
11747
|
+
return false;
|
|
11748
|
+
}
|
|
11749
|
+
const persistentCollection = {
|
|
11750
|
+
name: baseCollection.name,
|
|
11751
|
+
schema: baseCollection.schema,
|
|
11752
|
+
contentColumn: baseCollection.contentColumn,
|
|
11753
|
+
registry: baseCollection.registry,
|
|
11754
|
+
columns: baseCollection.columns,
|
|
11755
|
+
reactiveCount: baseCollection.reactiveCount,
|
|
11756
|
+
insert(data) {
|
|
11757
|
+
const id = baseCollection.insert(data);
|
|
11758
|
+
if (autoSave)
|
|
11759
|
+
saveRecord(id);
|
|
11760
|
+
return id;
|
|
11761
|
+
},
|
|
11762
|
+
insertMany(records) {
|
|
11763
|
+
const ids = baseCollection.insertMany(records);
|
|
11764
|
+
if (autoSave) {
|
|
11765
|
+
for (const id of ids)
|
|
11766
|
+
saveRecord(id);
|
|
11767
|
+
}
|
|
11768
|
+
return ids;
|
|
11769
|
+
},
|
|
11770
|
+
get: baseCollection.get.bind(baseCollection),
|
|
11771
|
+
all: baseCollection.all.bind(baseCollection),
|
|
11772
|
+
find: baseCollection.find.bind(baseCollection),
|
|
11773
|
+
findOne: baseCollection.findOne.bind(baseCollection),
|
|
11774
|
+
update(id, data) {
|
|
11775
|
+
const success = baseCollection.update(id, data);
|
|
11776
|
+
if (success && autoSave)
|
|
11777
|
+
saveRecord(id);
|
|
11778
|
+
return success;
|
|
11779
|
+
},
|
|
11780
|
+
updateField(id, field, value) {
|
|
11781
|
+
const success = baseCollection.updateField(id, field, value);
|
|
11782
|
+
if (success && autoSave)
|
|
11783
|
+
saveRecord(id);
|
|
11784
|
+
return success;
|
|
11785
|
+
},
|
|
11786
|
+
updateMany(filter, data) {
|
|
11787
|
+
const count = baseCollection.updateMany(filter, data);
|
|
11788
|
+
if (count > 0 && autoSave) {
|
|
11789
|
+
const updated = baseCollection.find(filter);
|
|
11790
|
+
for (const record of updated)
|
|
11791
|
+
saveRecord(record.id);
|
|
11792
|
+
}
|
|
11793
|
+
return count;
|
|
11794
|
+
},
|
|
11795
|
+
delete(id) {
|
|
11796
|
+
const success = baseCollection.delete(id);
|
|
11797
|
+
if (success && autoSave)
|
|
11798
|
+
deleteFile(id);
|
|
11799
|
+
embeddingManager.clearHash(id, "*");
|
|
11800
|
+
return success;
|
|
11801
|
+
},
|
|
11802
|
+
deleteMany(filter) {
|
|
11803
|
+
const toDelete = baseCollection.find(filter).map((r) => r.id);
|
|
11804
|
+
const count = baseCollection.deleteMany(filter);
|
|
11805
|
+
if (autoSave) {
|
|
11806
|
+
for (const id of toDelete)
|
|
11807
|
+
deleteFile(id);
|
|
11808
|
+
}
|
|
11809
|
+
for (const id of toDelete) {
|
|
11810
|
+
embeddingManager.clearHash(id, "*");
|
|
11811
|
+
}
|
|
11812
|
+
return count;
|
|
11813
|
+
},
|
|
11814
|
+
count: baseCollection.count.bind(baseCollection),
|
|
11815
|
+
getByIndex: baseCollection.getByIndex.bind(baseCollection),
|
|
11816
|
+
getIndices: baseCollection.getIndices.bind(baseCollection),
|
|
11817
|
+
has: baseCollection.has.bind(baseCollection),
|
|
11818
|
+
isStale: baseCollection.isStale.bind(baseCollection),
|
|
11819
|
+
getStaleIds: baseCollection.getStaleIds.bind(baseCollection),
|
|
11820
|
+
setStale: baseCollection.setStale.bind(baseCollection),
|
|
11821
|
+
setMetadata: baseCollection.setMetadata.bind(baseCollection),
|
|
11822
|
+
clear() {
|
|
11823
|
+
baseCollection.clear();
|
|
11824
|
+
embeddingManager.reset();
|
|
11825
|
+
},
|
|
11826
|
+
async load() {
|
|
11827
|
+
await ensureDirectory(path);
|
|
11828
|
+
const loaded = await loadFromDirectory(path, schema, contentColumn);
|
|
11829
|
+
for (const { id, record } of loaded) {
|
|
11830
|
+
const index = baseCollection.registry.allocate(id);
|
|
11831
|
+
baseCollection.columns.setRecord(index, record);
|
|
11832
|
+
const created = record.created ?? Date.now();
|
|
11833
|
+
const updated = record.updated ?? created;
|
|
11834
|
+
const stale = record.stale ?? false;
|
|
11835
|
+
baseCollection.setMetadata(id, created, updated, stale);
|
|
11836
|
+
if (contentColumn) {
|
|
11837
|
+
const content = record[contentColumn];
|
|
11838
|
+
if (content && isContentStale(id, content)) {
|
|
11839
|
+
baseCollection.setStale(id, true);
|
|
11009
11840
|
}
|
|
11010
11841
|
}
|
|
11011
|
-
}
|
|
11012
|
-
|
|
11013
|
-
|
|
11842
|
+
}
|
|
11843
|
+
return loaded.length;
|
|
11844
|
+
},
|
|
11845
|
+
async save() {
|
|
11846
|
+
await ensureDirectory(path);
|
|
11847
|
+
const records = baseCollection.all();
|
|
11848
|
+
for (const record of records) {
|
|
11849
|
+
await saveRecord(record.id);
|
|
11850
|
+
}
|
|
11851
|
+
return records.length;
|
|
11852
|
+
},
|
|
11853
|
+
startWatching() {
|
|
11854
|
+
if (fileWatcher)
|
|
11855
|
+
return;
|
|
11856
|
+
fileWatcher = createFileWatcher({
|
|
11857
|
+
dirpath: path,
|
|
11858
|
+
schema,
|
|
11859
|
+
contentColumn,
|
|
11860
|
+
isStaleCallback: contentColumn ? (id, content) => isContentStale(id, content) : undefined
|
|
11861
|
+
});
|
|
11862
|
+
fileWatcher.onChange(async (event) => {
|
|
11863
|
+
if (savingIds.has(event.id))
|
|
11014
11864
|
return;
|
|
11015
|
-
|
|
11016
|
-
|
|
11017
|
-
if (
|
|
11018
|
-
const
|
|
11019
|
-
|
|
11020
|
-
|
|
11021
|
-
|
|
11022
|
-
|
|
11023
|
-
break;
|
|
11024
|
-
}
|
|
11025
|
-
}
|
|
11026
|
-
}
|
|
11027
|
-
this._staleFlags[index] = isStale;
|
|
11028
|
-
for (const [key, value] of Object.entries(doc.frontmatter)) {
|
|
11029
|
-
if (key === "id")
|
|
11030
|
-
continue;
|
|
11031
|
-
if (key === "created") {
|
|
11032
|
-
this._created[index] = value;
|
|
11033
|
-
continue;
|
|
11034
|
-
}
|
|
11035
|
-
if (key === "updated") {
|
|
11036
|
-
this._updated[index] = value;
|
|
11037
|
-
continue;
|
|
11865
|
+
if (event.type === "delete") {
|
|
11866
|
+
baseCollection.delete(event.id);
|
|
11867
|
+
} else if (event.record) {
|
|
11868
|
+
const exists = baseCollection.has(event.id);
|
|
11869
|
+
if (exists) {
|
|
11870
|
+
baseCollection.update(event.id, event.record);
|
|
11871
|
+
} else {
|
|
11872
|
+
baseCollection.insert({ ...event.record, id: event.id });
|
|
11038
11873
|
}
|
|
11039
|
-
|
|
11040
|
-
|
|
11041
|
-
if (Array.isArray(value)) {
|
|
11042
|
-
this._columns.set(key, index, toFloat32Array(value));
|
|
11043
|
-
}
|
|
11044
|
-
} else if (key in this._options.schema) {
|
|
11045
|
-
this._columns.set(key, index, value);
|
|
11874
|
+
if (event.stale) {
|
|
11875
|
+
baseCollection.setStale(event.id, true);
|
|
11046
11876
|
}
|
|
11047
11877
|
}
|
|
11048
|
-
if (
|
|
11049
|
-
|
|
11050
|
-
}
|
|
11051
|
-
if (this._onFileChange) {
|
|
11052
|
-
const record = this._columns.getRecord(index);
|
|
11053
|
-
this._onFileChange({ ...event, record, stale: isStale });
|
|
11878
|
+
if (onExternalChange) {
|
|
11879
|
+
await onExternalChange(event);
|
|
11054
11880
|
}
|
|
11881
|
+
});
|
|
11882
|
+
fileWatcher.start();
|
|
11883
|
+
},
|
|
11884
|
+
stopWatching() {
|
|
11885
|
+
if (fileWatcher) {
|
|
11886
|
+
fileWatcher.stop();
|
|
11887
|
+
fileWatcher = null;
|
|
11888
|
+
}
|
|
11889
|
+
},
|
|
11890
|
+
get isWatching() {
|
|
11891
|
+
return fileWatcher?.isWatching ?? false;
|
|
11892
|
+
},
|
|
11893
|
+
onFileChange(callback) {
|
|
11894
|
+
if (!fileWatcher) {
|
|
11895
|
+
persistentCollection.startWatching();
|
|
11055
11896
|
}
|
|
11056
|
-
|
|
11057
|
-
|
|
11897
|
+
return fileWatcher.onChange(callback);
|
|
11898
|
+
},
|
|
11899
|
+
setEmbedding(id, column, embedding, sourceContent) {
|
|
11900
|
+
const vec = embedding instanceof Float32Array ? embedding : new Float32Array(embedding);
|
|
11901
|
+
baseCollection.updateField(id, column, vec);
|
|
11902
|
+
embeddingManager.setEmbedding(id, String(column), sourceContent);
|
|
11903
|
+
baseCollection.setStale(id, false);
|
|
11904
|
+
if (autoSave)
|
|
11905
|
+
saveRecord(id);
|
|
11906
|
+
},
|
|
11907
|
+
search(column, queryVector, options2) {
|
|
11908
|
+
return vectorSearch(baseCollection, column, queryVector, options2);
|
|
11909
|
+
},
|
|
11910
|
+
close() {
|
|
11911
|
+
persistentCollection.stopWatching();
|
|
11912
|
+
baseCollection.clear();
|
|
11913
|
+
embeddingManager.reset();
|
|
11058
11914
|
}
|
|
11915
|
+
};
|
|
11916
|
+
if (watchFiles) {
|
|
11917
|
+
persistentCollection.startWatching();
|
|
11918
|
+
}
|
|
11919
|
+
return persistentCollection;
|
|
11920
|
+
}
|
|
11921
|
+
function createDatabase(options = {}) {
|
|
11922
|
+
const name = options.name ?? "default";
|
|
11923
|
+
let basePath;
|
|
11924
|
+
if (options.basePath) {
|
|
11925
|
+
basePath = options.basePath;
|
|
11926
|
+
} else if (options.local) {
|
|
11927
|
+
basePath = `${process.cwd()}/.fsdb/${name}`;
|
|
11928
|
+
} else {
|
|
11929
|
+
basePath = `${Bun.env.HOME}/.fsdb/${name}`;
|
|
11059
11930
|
}
|
|
11060
|
-
|
|
11061
|
-
|
|
11062
|
-
|
|
11063
|
-
|
|
11064
|
-
|
|
11065
|
-
|
|
11066
|
-
|
|
11067
|
-
|
|
11068
|
-
|
|
11069
|
-
const
|
|
11070
|
-
|
|
11071
|
-
|
|
11072
|
-
|
|
11073
|
-
|
|
11074
|
-
|
|
11931
|
+
const collections = new ReactiveMap;
|
|
11932
|
+
return {
|
|
11933
|
+
name,
|
|
11934
|
+
basePath,
|
|
11935
|
+
collection(collectionName, collectionOptions) {
|
|
11936
|
+
const existing = collections.get(collectionName);
|
|
11937
|
+
if (existing) {
|
|
11938
|
+
return existing;
|
|
11939
|
+
}
|
|
11940
|
+
const path = `${basePath}/${collectionName}`;
|
|
11941
|
+
const collection = createPersistentCollection(collectionName, {
|
|
11942
|
+
...collectionOptions,
|
|
11943
|
+
path
|
|
11944
|
+
});
|
|
11945
|
+
collections.set(collectionName, collection);
|
|
11946
|
+
return collection;
|
|
11947
|
+
},
|
|
11948
|
+
getCollection(collectionName) {
|
|
11949
|
+
return collections.get(collectionName);
|
|
11950
|
+
},
|
|
11951
|
+
listCollections() {
|
|
11952
|
+
return Array.from(collections.keys());
|
|
11953
|
+
},
|
|
11954
|
+
close() {
|
|
11955
|
+
for (const collection of collections.values()) {
|
|
11956
|
+
collection.close();
|
|
11957
|
+
}
|
|
11958
|
+
collections.clear();
|
|
11075
11959
|
}
|
|
11076
|
-
}
|
|
11077
|
-
return db;
|
|
11960
|
+
};
|
|
11078
11961
|
}
|
|
11079
11962
|
|
|
11080
11963
|
// src/core/store.ts
|
|
11081
11964
|
import { homedir } from "os";
|
|
11082
|
-
import { join
|
|
11965
|
+
import { join } from "path";
|
|
11083
11966
|
|
|
11084
11967
|
// src/types/schema.ts
|
|
11085
11968
|
var memorySchema = {
|
|
@@ -11128,7 +12011,7 @@ class MemoryStore {
|
|
|
11128
12011
|
_projects = new Map;
|
|
11129
12012
|
constructor(config = {}) {
|
|
11130
12013
|
this._config = {
|
|
11131
|
-
basePath: config.basePath ??
|
|
12014
|
+
basePath: config.basePath ?? join(homedir(), ".local", "share", "memory"),
|
|
11132
12015
|
watchFiles: config.watchFiles ?? false
|
|
11133
12016
|
};
|
|
11134
12017
|
}
|
|
@@ -11138,43 +12021,47 @@ class MemoryStore {
|
|
|
11138
12021
|
return this._projects.get(projectId);
|
|
11139
12022
|
}
|
|
11140
12023
|
console.log(`\uD83C\uDD95 [DEBUG] Creating NEW databases for ${projectId}`);
|
|
11141
|
-
const projectPath =
|
|
12024
|
+
const projectPath = join(this._config.basePath, projectId);
|
|
11142
12025
|
console.log(` Path: ${projectPath}`);
|
|
11143
|
-
const
|
|
11144
|
-
|
|
11145
|
-
|
|
11146
|
-
|
|
11147
|
-
|
|
11148
|
-
|
|
11149
|
-
|
|
11150
|
-
|
|
11151
|
-
|
|
11152
|
-
|
|
11153
|
-
|
|
11154
|
-
|
|
11155
|
-
|
|
11156
|
-
|
|
11157
|
-
|
|
11158
|
-
|
|
11159
|
-
|
|
11160
|
-
|
|
11161
|
-
|
|
11162
|
-
|
|
11163
|
-
|
|
11164
|
-
|
|
11165
|
-
|
|
11166
|
-
|
|
11167
|
-
|
|
11168
|
-
|
|
11169
|
-
|
|
12026
|
+
const db = createDatabase({
|
|
12027
|
+
name: projectId,
|
|
12028
|
+
basePath: projectPath
|
|
12029
|
+
});
|
|
12030
|
+
const memories = db.collection("memories", {
|
|
12031
|
+
schema: memorySchema,
|
|
12032
|
+
contentColumn: "content",
|
|
12033
|
+
autoSave: true,
|
|
12034
|
+
watchFiles: this._config.watchFiles
|
|
12035
|
+
});
|
|
12036
|
+
const summaries = db.collection("summaries", {
|
|
12037
|
+
schema: sessionSummarySchema,
|
|
12038
|
+
contentColumn: "summary",
|
|
12039
|
+
autoSave: true,
|
|
12040
|
+
watchFiles: this._config.watchFiles
|
|
12041
|
+
});
|
|
12042
|
+
const snapshots = db.collection("snapshots", {
|
|
12043
|
+
schema: projectSnapshotSchema,
|
|
12044
|
+
autoSave: true,
|
|
12045
|
+
watchFiles: this._config.watchFiles
|
|
12046
|
+
});
|
|
12047
|
+
const sessions = db.collection("sessions", {
|
|
12048
|
+
schema: sessionSchema,
|
|
12049
|
+
autoSave: true,
|
|
12050
|
+
watchFiles: this._config.watchFiles
|
|
12051
|
+
});
|
|
12052
|
+
await Promise.all([
|
|
12053
|
+
memories.load(),
|
|
12054
|
+
summaries.load(),
|
|
12055
|
+
snapshots.load(),
|
|
12056
|
+
sessions.load()
|
|
11170
12057
|
]);
|
|
11171
|
-
const
|
|
11172
|
-
this._projects.set(projectId,
|
|
11173
|
-
return
|
|
12058
|
+
const projectDB = { db, memories, summaries, snapshots, sessions };
|
|
12059
|
+
this._projects.set(projectId, projectDB);
|
|
12060
|
+
return projectDB;
|
|
11174
12061
|
}
|
|
11175
12062
|
async storeMemory(projectId, sessionId, memory, embedding) {
|
|
11176
12063
|
const { memories } = await this.getProject(projectId);
|
|
11177
|
-
const id =
|
|
12064
|
+
const id = memories.insert({
|
|
11178
12065
|
content: memory.content,
|
|
11179
12066
|
reasoning: memory.reasoning,
|
|
11180
12067
|
importance_weight: memory.importance_weight,
|
|
@@ -11190,7 +12077,7 @@ class MemoryStore {
|
|
|
11190
12077
|
question_types: memory.question_types,
|
|
11191
12078
|
session_id: sessionId,
|
|
11192
12079
|
project_id: projectId,
|
|
11193
|
-
embedding: embedding ? embedding instanceof Float32Array ? embedding : new Float32Array(embedding) :
|
|
12080
|
+
embedding: embedding ? embedding instanceof Float32Array ? embedding : new Float32Array(embedding) : null
|
|
11194
12081
|
});
|
|
11195
12082
|
return id;
|
|
11196
12083
|
}
|
|
@@ -11213,7 +12100,7 @@ class MemoryStore {
|
|
|
11213
12100
|
question_types: record.question_types,
|
|
11214
12101
|
session_id: record.session_id,
|
|
11215
12102
|
project_id: record.project_id,
|
|
11216
|
-
embedding: record.embedding,
|
|
12103
|
+
embedding: record.embedding ?? undefined,
|
|
11217
12104
|
created_at: record.created,
|
|
11218
12105
|
updated_at: record.updated,
|
|
11219
12106
|
stale: record.stale
|
|
@@ -11224,9 +12111,9 @@ class MemoryStore {
|
|
|
11224
12111
|
const { topK = 10, filter } = options;
|
|
11225
12112
|
const results = memories.search("embedding", queryEmbedding, {
|
|
11226
12113
|
topK,
|
|
11227
|
-
filter: filter ? (record) => {
|
|
12114
|
+
filter: filter ? (record, _idx) => {
|
|
11228
12115
|
const mem = {
|
|
11229
|
-
id:
|
|
12116
|
+
id: "",
|
|
11230
12117
|
content: record.content,
|
|
11231
12118
|
reasoning: record.reasoning,
|
|
11232
12119
|
importance_weight: record.importance_weight,
|
|
@@ -11248,36 +12135,37 @@ class MemoryStore {
|
|
|
11248
12135
|
return filter(mem);
|
|
11249
12136
|
} : undefined
|
|
11250
12137
|
});
|
|
11251
|
-
return results.map((
|
|
11252
|
-
id: record.id,
|
|
11253
|
-
content: record.content,
|
|
11254
|
-
reasoning: record.reasoning,
|
|
11255
|
-
importance_weight: record.importance_weight,
|
|
11256
|
-
confidence_score: record.confidence_score,
|
|
11257
|
-
context_type: record.context_type,
|
|
11258
|
-
temporal_relevance: record.temporal_relevance,
|
|
11259
|
-
knowledge_domain: record.knowledge_domain,
|
|
11260
|
-
emotional_resonance: record.emotional_resonance,
|
|
11261
|
-
action_required: record.action_required,
|
|
11262
|
-
problem_solution_pair: record.problem_solution_pair,
|
|
11263
|
-
semantic_tags: record.semantic_tags,
|
|
11264
|
-
trigger_phrases: record.trigger_phrases,
|
|
11265
|
-
question_types: record.question_types,
|
|
11266
|
-
session_id: record.session_id,
|
|
11267
|
-
project_id: record.project_id,
|
|
11268
|
-
embedding: record.embedding,
|
|
11269
|
-
created_at: record.created,
|
|
11270
|
-
updated_at: record.updated,
|
|
11271
|
-
stale:
|
|
12138
|
+
return results.map((result) => ({
|
|
12139
|
+
id: result.record.id,
|
|
12140
|
+
content: result.record.content,
|
|
12141
|
+
reasoning: result.record.reasoning,
|
|
12142
|
+
importance_weight: result.record.importance_weight,
|
|
12143
|
+
confidence_score: result.record.confidence_score,
|
|
12144
|
+
context_type: result.record.context_type,
|
|
12145
|
+
temporal_relevance: result.record.temporal_relevance,
|
|
12146
|
+
knowledge_domain: result.record.knowledge_domain,
|
|
12147
|
+
emotional_resonance: result.record.emotional_resonance,
|
|
12148
|
+
action_required: result.record.action_required,
|
|
12149
|
+
problem_solution_pair: result.record.problem_solution_pair,
|
|
12150
|
+
semantic_tags: result.record.semantic_tags,
|
|
12151
|
+
trigger_phrases: result.record.trigger_phrases,
|
|
12152
|
+
question_types: result.record.question_types,
|
|
12153
|
+
session_id: result.record.session_id,
|
|
12154
|
+
project_id: result.record.project_id,
|
|
12155
|
+
embedding: result.record.embedding ?? undefined,
|
|
12156
|
+
created_at: result.record.created,
|
|
12157
|
+
updated_at: result.record.updated,
|
|
12158
|
+
stale: result.stale
|
|
11272
12159
|
}));
|
|
11273
12160
|
}
|
|
11274
12161
|
async setMemoryEmbedding(projectId, memoryId, embedding, content) {
|
|
11275
12162
|
const { memories } = await this.getProject(projectId);
|
|
11276
|
-
|
|
12163
|
+
const vec = embedding instanceof Float32Array ? embedding : new Float32Array(embedding);
|
|
12164
|
+
memories.setEmbedding(memoryId, "embedding", vec, content);
|
|
11277
12165
|
}
|
|
11278
12166
|
async getStaleMemoryIds(projectId) {
|
|
11279
12167
|
const { memories } = await this.getProject(projectId);
|
|
11280
|
-
return memories.
|
|
12168
|
+
return memories.all().filter((r) => r.stale).map((r) => r.id);
|
|
11281
12169
|
}
|
|
11282
12170
|
async getOrCreateSession(projectId, sessionId) {
|
|
11283
12171
|
const { sessions } = await this.getProject(projectId);
|
|
@@ -11291,7 +12179,7 @@ class MemoryStore {
|
|
|
11291
12179
|
}
|
|
11292
12180
|
const allSessions = sessions.all();
|
|
11293
12181
|
const firstSessionCompleted = allSessions.some((s) => s.first_session_completed);
|
|
11294
|
-
|
|
12182
|
+
sessions.insert({
|
|
11295
12183
|
id: sessionId,
|
|
11296
12184
|
project_id: projectId,
|
|
11297
12185
|
message_count: 0,
|
|
@@ -11312,7 +12200,7 @@ class MemoryStore {
|
|
|
11312
12200
|
throw new Error(`Session ${sessionId} not found`);
|
|
11313
12201
|
}
|
|
11314
12202
|
const newCount = session.message_count + 1;
|
|
11315
|
-
|
|
12203
|
+
sessions.update(sessionId, {
|
|
11316
12204
|
message_count: newCount,
|
|
11317
12205
|
last_active: Date.now()
|
|
11318
12206
|
});
|
|
@@ -11320,14 +12208,14 @@ class MemoryStore {
|
|
|
11320
12208
|
}
|
|
11321
12209
|
async markFirstSessionCompleted(projectId, sessionId) {
|
|
11322
12210
|
const { sessions } = await this.getProject(projectId);
|
|
11323
|
-
|
|
12211
|
+
sessions.update(sessionId, { first_session_completed: true });
|
|
11324
12212
|
}
|
|
11325
12213
|
async storeSessionSummary(projectId, sessionId, summary, interactionTone = "") {
|
|
11326
12214
|
const { summaries } = await this.getProject(projectId);
|
|
11327
12215
|
console.log(`\uD83D\uDCDD [DEBUG] Storing summary for ${projectId}:`);
|
|
11328
12216
|
console.log(` Summary length: ${summary.length} chars`);
|
|
11329
12217
|
console.log(` Summaries count before: ${summaries.all().length}`);
|
|
11330
|
-
const id =
|
|
12218
|
+
const id = summaries.insert({
|
|
11331
12219
|
session_id: sessionId,
|
|
11332
12220
|
project_id: projectId,
|
|
11333
12221
|
summary,
|
|
@@ -11346,8 +12234,8 @@ class MemoryStore {
|
|
|
11346
12234
|
console.log(` No summaries found!`);
|
|
11347
12235
|
return null;
|
|
11348
12236
|
}
|
|
11349
|
-
all.sort((a, b) => b.created - a.created);
|
|
11350
|
-
const latest =
|
|
12237
|
+
const sorted = [...all].sort((a, b) => b.created - a.created);
|
|
12238
|
+
const latest = sorted[0];
|
|
11351
12239
|
console.log(` Latest summary: ${latest.summary.slice(0, 50)}...`);
|
|
11352
12240
|
return {
|
|
11353
12241
|
id: latest.id,
|
|
@@ -11374,8 +12262,8 @@ class MemoryStore {
|
|
|
11374
12262
|
const all = snapshots.all();
|
|
11375
12263
|
if (!all.length)
|
|
11376
12264
|
return null;
|
|
11377
|
-
all.sort((a, b) => b.created - a.created);
|
|
11378
|
-
const latest =
|
|
12265
|
+
const sorted = [...all].sort((a, b) => b.created - a.created);
|
|
12266
|
+
const latest = sorted[0];
|
|
11379
12267
|
return {
|
|
11380
12268
|
id: latest.id,
|
|
11381
12269
|
session_id: latest.session_id,
|
|
@@ -11391,25 +12279,22 @@ class MemoryStore {
|
|
|
11391
12279
|
const { memories, sessions } = await this.getProject(projectId);
|
|
11392
12280
|
const allMemories = memories.all();
|
|
11393
12281
|
const allSessions = sessions.all();
|
|
11394
|
-
const
|
|
12282
|
+
const staleCount = allMemories.filter((r) => r.stale).length;
|
|
11395
12283
|
let latestSession = null;
|
|
11396
12284
|
if (allSessions.length) {
|
|
11397
|
-
allSessions.sort((a, b) => b.last_active - a.last_active);
|
|
11398
|
-
latestSession =
|
|
12285
|
+
const sorted = [...allSessions].sort((a, b) => b.last_active - a.last_active);
|
|
12286
|
+
latestSession = sorted[0].id;
|
|
11399
12287
|
}
|
|
11400
12288
|
return {
|
|
11401
12289
|
totalMemories: allMemories.length,
|
|
11402
12290
|
totalSessions: allSessions.length,
|
|
11403
|
-
staleMemories:
|
|
12291
|
+
staleMemories: staleCount,
|
|
11404
12292
|
latestSession
|
|
11405
12293
|
};
|
|
11406
12294
|
}
|
|
11407
12295
|
close() {
|
|
11408
|
-
for (const
|
|
11409
|
-
|
|
11410
|
-
dbs.summaries.close();
|
|
11411
|
-
dbs.snapshots.close();
|
|
11412
|
-
dbs.sessions.close();
|
|
12296
|
+
for (const projectDB of this._projects.values()) {
|
|
12297
|
+
projectDB.db.close();
|
|
11413
12298
|
}
|
|
11414
12299
|
this._projects.clear();
|
|
11415
12300
|
}
|
|
@@ -11418,9 +12303,205 @@ function createStore(config) {
|
|
|
11418
12303
|
return new MemoryStore(config);
|
|
11419
12304
|
}
|
|
11420
12305
|
|
|
12306
|
+
// src/utils/logger.ts
|
|
12307
|
+
import { styleText } from "util";
|
|
12308
|
+
var style = (format, text) => styleText(format, text);
|
|
12309
|
+
function timestamp() {
|
|
12310
|
+
return style("dim", new Date().toISOString().slice(11, 19));
|
|
12311
|
+
}
|
|
12312
|
+
function shortId(id) {
|
|
12313
|
+
return style("dim", id.slice(0, 8) + "...");
|
|
12314
|
+
}
|
|
12315
|
+
var sym = {
|
|
12316
|
+
brain: "\uD83E\uDDE0",
|
|
12317
|
+
sparkles: "✨",
|
|
12318
|
+
book: "\uD83D\uDCD6",
|
|
12319
|
+
calendar: "\uD83D\uDCC5",
|
|
12320
|
+
arrow: "→",
|
|
12321
|
+
check: "✓",
|
|
12322
|
+
cross: "✗",
|
|
12323
|
+
warning: "⚠",
|
|
12324
|
+
info: "ℹ",
|
|
12325
|
+
bullet: "•",
|
|
12326
|
+
fire: "\uD83D\uDD25",
|
|
12327
|
+
target: "\uD83C\uDFAF"
|
|
12328
|
+
};
|
|
12329
|
+
var logger = {
|
|
12330
|
+
info(message) {
|
|
12331
|
+
console.log(`${timestamp()} ${style("cyan", sym.info)} ${message}`);
|
|
12332
|
+
},
|
|
12333
|
+
success(message) {
|
|
12334
|
+
console.log(`${timestamp()} ${style("green", sym.check)} ${message}`);
|
|
12335
|
+
},
|
|
12336
|
+
warn(message) {
|
|
12337
|
+
console.log(`${timestamp()} ${style("yellow", sym.warning)} ${message}`);
|
|
12338
|
+
},
|
|
12339
|
+
error(message) {
|
|
12340
|
+
console.error(`${timestamp()} ${style("red", sym.cross)} ${message}`);
|
|
12341
|
+
},
|
|
12342
|
+
memory(message) {
|
|
12343
|
+
console.log(`${timestamp()} ${style("magenta", sym.brain)} ${message}`);
|
|
12344
|
+
},
|
|
12345
|
+
inject(message) {
|
|
12346
|
+
console.log(`${timestamp()} ${style("cyan", sym.sparkles)} ${message}`);
|
|
12347
|
+
},
|
|
12348
|
+
session(message) {
|
|
12349
|
+
console.log(`${timestamp()} ${style("blue", sym.calendar)} ${message}`);
|
|
12350
|
+
},
|
|
12351
|
+
primer(message) {
|
|
12352
|
+
console.log(`${timestamp()} ${style("yellow", sym.book)} ${message}`);
|
|
12353
|
+
},
|
|
12354
|
+
divider() {
|
|
12355
|
+
console.log(style("dim", "─".repeat(60)));
|
|
12356
|
+
},
|
|
12357
|
+
request(method, path, projectId) {
|
|
12358
|
+
const proj = projectId ? style("dim", ` [${projectId}]`) : "";
|
|
12359
|
+
console.log(`${timestamp()} ${style("dim", sym.arrow)} ${style("cyan", method)} ${path}${proj}`);
|
|
12360
|
+
},
|
|
12361
|
+
logCuratedMemories(memories) {
|
|
12362
|
+
console.log();
|
|
12363
|
+
console.log(`${timestamp()} ${style("magenta", sym.brain)} ${style(["bold", "magenta"], `CURATED ${memories.length} MEMORIES`)}`);
|
|
12364
|
+
console.log();
|
|
12365
|
+
memories.forEach((m, i) => {
|
|
12366
|
+
const importance = style("yellow", `${(m.importance_weight * 100).toFixed(0)}%`);
|
|
12367
|
+
const type = style("cyan", m.context_type.toUpperCase());
|
|
12368
|
+
const num = style("dim", `${i + 1}.`);
|
|
12369
|
+
console.log(` ${num} [${type}] ${importance}`);
|
|
12370
|
+
const preview = m.content.length > 70 ? m.content.slice(0, 70) + style("dim", "...") : m.content;
|
|
12371
|
+
console.log(` ${style("white", preview)}`);
|
|
12372
|
+
if (m.semantic_tags?.length) {
|
|
12373
|
+
const tags = m.semantic_tags.slice(0, 4).join(style("dim", ", "));
|
|
12374
|
+
console.log(` ${style("dim", "tags:")} ${tags}`);
|
|
12375
|
+
}
|
|
12376
|
+
if (m.action_required) {
|
|
12377
|
+
console.log(` ${style("red", "⚡ ACTION REQUIRED")}`);
|
|
12378
|
+
}
|
|
12379
|
+
console.log();
|
|
12380
|
+
});
|
|
12381
|
+
},
|
|
12382
|
+
logRetrievedMemories(memories, query) {
|
|
12383
|
+
const queryPreview = query.length > 40 ? query.slice(0, 40) + "..." : query;
|
|
12384
|
+
const emojiMap = {
|
|
12385
|
+
breakthrough: "\uD83D\uDCA1",
|
|
12386
|
+
decision: "⚖️",
|
|
12387
|
+
personal: "\uD83D\uDC9C",
|
|
12388
|
+
technical: "\uD83D\uDD27",
|
|
12389
|
+
technical_state: "\uD83D\uDCCD",
|
|
12390
|
+
unresolved: "❓",
|
|
12391
|
+
preference: "⚙️",
|
|
12392
|
+
workflow: "\uD83D\uDD04",
|
|
12393
|
+
architectural: "\uD83C\uDFD7️",
|
|
12394
|
+
debugging: "\uD83D\uDC1B",
|
|
12395
|
+
philosophy: "\uD83C\uDF00",
|
|
12396
|
+
todo: "\uD83C\uDFAF",
|
|
12397
|
+
implementation: "⚡",
|
|
12398
|
+
problem_solution: "✅",
|
|
12399
|
+
project_context: "\uD83D\uDCE6",
|
|
12400
|
+
milestone: "\uD83C\uDFC6",
|
|
12401
|
+
general: "\uD83D\uDCDD"
|
|
12402
|
+
};
|
|
12403
|
+
console.log();
|
|
12404
|
+
console.log(`${timestamp()} ${style("cyan", sym.sparkles)} ${style("bold", `SURFACING ${memories.length} MEMORIES`)}`);
|
|
12405
|
+
console.log(` ${style("dim", "query:")} "${queryPreview}"`);
|
|
12406
|
+
console.log();
|
|
12407
|
+
if (memories.length === 0) {
|
|
12408
|
+
console.log(` ${style("dim", "(no relevant memories for this context)")}`);
|
|
12409
|
+
console.log();
|
|
12410
|
+
return;
|
|
12411
|
+
}
|
|
12412
|
+
memories.forEach((m, i) => {
|
|
12413
|
+
const score = style("green", `${(m.score * 100).toFixed(0)}%`);
|
|
12414
|
+
const emoji = emojiMap[m.context_type?.toLowerCase()] ?? "\uD83D\uDCDD";
|
|
12415
|
+
const num = style("dim", `${i + 1}.`);
|
|
12416
|
+
const preview = m.content.length > 55 ? m.content.slice(0, 55) + style("dim", "...") : m.content;
|
|
12417
|
+
console.log(` ${num} [${score}] ${emoji}`);
|
|
12418
|
+
console.log(` ${preview}`);
|
|
12419
|
+
});
|
|
12420
|
+
console.log();
|
|
12421
|
+
},
|
|
12422
|
+
startup(port, host, mode) {
|
|
12423
|
+
console.log();
|
|
12424
|
+
console.log(style(["bold", "magenta"], "┌──────────────────────────────────────────────────────────┐"));
|
|
12425
|
+
console.log(style(["bold", "magenta"], "│") + style("bold", ` ${sym.brain} MEMORY SERVER `) + style(["bold", "magenta"], "│"));
|
|
12426
|
+
console.log(style(["bold", "magenta"], "└──────────────────────────────────────────────────────────┘"));
|
|
12427
|
+
console.log();
|
|
12428
|
+
console.log(` ${style("dim", "url:")} ${style("cyan", `http://${host}:${port}`)}`);
|
|
12429
|
+
console.log(` ${style("dim", "storage:")} ${mode}`);
|
|
12430
|
+
console.log(` ${style("dim", "engine:")} TypeScript + fsdb`);
|
|
12431
|
+
console.log();
|
|
12432
|
+
this.divider();
|
|
12433
|
+
console.log();
|
|
12434
|
+
},
|
|
12435
|
+
logSessionStart(sessionId, projectId, isNew) {
|
|
12436
|
+
const status = isNew ? style("green", "new session") : style("blue", "continuing");
|
|
12437
|
+
console.log();
|
|
12438
|
+
console.log(`${timestamp()} ${style("blue", sym.calendar)} ${style("bold", "SESSION")} ${shortId(sessionId)}`);
|
|
12439
|
+
console.log(` ${style("dim", "project:")} ${projectId}`);
|
|
12440
|
+
console.log(` ${style("dim", "status:")} ${status}`);
|
|
12441
|
+
console.log();
|
|
12442
|
+
},
|
|
12443
|
+
logCurationStart(sessionId, trigger) {
|
|
12444
|
+
console.log();
|
|
12445
|
+
console.log(`${timestamp()} ${style("magenta", sym.brain)} ${style("bold", "CURATING")} ${shortId(sessionId)}`);
|
|
12446
|
+
console.log(` ${style("dim", "trigger:")} ${trigger}`);
|
|
12447
|
+
},
|
|
12448
|
+
logCurationComplete(memoriesCount, summary) {
|
|
12449
|
+
if (memoriesCount > 0) {
|
|
12450
|
+
console.log(` ${style("dim", "memories:")} ${style("green", String(memoriesCount))} extracted`);
|
|
12451
|
+
if (summary) {
|
|
12452
|
+
const shortSummary = summary.length > 50 ? summary.slice(0, 50) + "..." : summary;
|
|
12453
|
+
console.log(` ${style("dim", "summary:")} ${shortSummary}`);
|
|
12454
|
+
}
|
|
12455
|
+
} else {
|
|
12456
|
+
console.log(` ${style("dim", "result:")} no memories to extract`);
|
|
12457
|
+
}
|
|
12458
|
+
console.log();
|
|
12459
|
+
},
|
|
12460
|
+
logRetrievalScoring(params) {
|
|
12461
|
+
const { totalMemories, currentMessage, alreadyInjected, mustIncludeCount, remainingSlots, finalCount, selectedMemories } = params;
|
|
12462
|
+
console.log();
|
|
12463
|
+
console.log(`${timestamp()} ${style("magenta", sym.brain)} ${style("bold", "TWO-STAGE MEMORY FILTERING")}`);
|
|
12464
|
+
console.log(` ${style("dim", "candidates:")} ${totalMemories} memories`);
|
|
12465
|
+
console.log(` ${style("dim", "already injected:")} ${alreadyInjected}`);
|
|
12466
|
+
const msgPreview = currentMessage.length > 60 ? currentMessage.slice(0, 60) + "..." : currentMessage;
|
|
12467
|
+
console.log(` ${style("dim", "trigger:")} "${msgPreview}"`);
|
|
12468
|
+
console.log();
|
|
12469
|
+
console.log(` ${style("cyan", "Stage 1:")} ${mustIncludeCount} must-include (critical/action-required)`);
|
|
12470
|
+
console.log(` ${style("cyan", "Stage 2:")} ${remainingSlots} slots for scored selection`);
|
|
12471
|
+
console.log(` ${style("green", "Final:")} ${finalCount} memories selected`);
|
|
12472
|
+
console.log();
|
|
12473
|
+
if (selectedMemories.length === 0) {
|
|
12474
|
+
console.log(` ${style("dim", "\uD83D\uDCED No relevant memories for this context")}`);
|
|
12475
|
+
console.log();
|
|
12476
|
+
return;
|
|
12477
|
+
}
|
|
12478
|
+
console.log(style("dim", " ─".repeat(30)));
|
|
12479
|
+
console.log(` ${style("bold", "SELECTION DETAILS")}`);
|
|
12480
|
+
console.log();
|
|
12481
|
+
selectedMemories.forEach((m, i) => {
|
|
12482
|
+
const num = style("dim", `${i + 1}.`);
|
|
12483
|
+
const score = style("green", `${(m.score * 100).toFixed(0)}%`);
|
|
12484
|
+
const relevance = style("cyan", `rel:${(m.relevance_score * 100).toFixed(0)}%`);
|
|
12485
|
+
const type = style("yellow", m.context_type.toUpperCase());
|
|
12486
|
+
console.log(` ${num} [${score} ${relevance}] ${type}`);
|
|
12487
|
+
const preview = m.content.length > 60 ? m.content.slice(0, 60) + style("dim", "...") : m.content;
|
|
12488
|
+
console.log(` ${style("white", preview)}`);
|
|
12489
|
+
const components = Object.entries(m.components).sort((a, b) => b[1] - a[1]).slice(0, 3).filter(([, v]) => v > 0.1).map(([k, v]) => `${k}:${(v * 100).toFixed(0)}%`).join(", ");
|
|
12490
|
+
if (components) {
|
|
12491
|
+
console.log(` ${style("dim", "scores:")} ${components}`);
|
|
12492
|
+
}
|
|
12493
|
+
if (m.semantic_tags?.length) {
|
|
12494
|
+
const tags = m.semantic_tags.slice(0, 3).join(", ");
|
|
12495
|
+
console.log(` ${style("dim", "tags:")} ${tags}`);
|
|
12496
|
+
}
|
|
12497
|
+
console.log();
|
|
12498
|
+
});
|
|
12499
|
+
}
|
|
12500
|
+
};
|
|
12501
|
+
|
|
11421
12502
|
// src/core/retrieval.ts
|
|
11422
12503
|
class SmartVectorRetrieval {
|
|
11423
|
-
retrieveRelevantMemories(allMemories, currentMessage, queryEmbedding, sessionContext, maxMemories = 5) {
|
|
12504
|
+
retrieveRelevantMemories(allMemories, currentMessage, queryEmbedding, sessionContext, maxMemories = 5, alreadyInjectedCount = 0) {
|
|
11424
12505
|
if (!allMemories.length) {
|
|
11425
12506
|
return [];
|
|
11426
12507
|
}
|
|
@@ -11519,6 +12600,24 @@ class SmartVectorRetrieval {
|
|
|
11519
12600
|
}
|
|
11520
12601
|
}
|
|
11521
12602
|
const finalSelected = selected.slice(0, maxMemories);
|
|
12603
|
+
logger.logRetrievalScoring({
|
|
12604
|
+
totalMemories: allMemories.length,
|
|
12605
|
+
currentMessage,
|
|
12606
|
+
alreadyInjected: alreadyInjectedCount,
|
|
12607
|
+
mustIncludeCount: mustInclude.length,
|
|
12608
|
+
remainingSlots,
|
|
12609
|
+
finalCount: finalSelected.length,
|
|
12610
|
+
selectedMemories: finalSelected.map((item) => ({
|
|
12611
|
+
content: item.memory.content,
|
|
12612
|
+
reasoning: item.reasoning,
|
|
12613
|
+
score: item.score,
|
|
12614
|
+
relevance_score: item.relevance_score,
|
|
12615
|
+
importance_weight: item.memory.importance_weight ?? 0.5,
|
|
12616
|
+
context_type: item.memory.context_type ?? "general",
|
|
12617
|
+
semantic_tags: item.memory.semantic_tags ?? [],
|
|
12618
|
+
components: item.components
|
|
12619
|
+
}))
|
|
12620
|
+
});
|
|
11522
12621
|
return finalSelected.map((item) => ({
|
|
11523
12622
|
...item.memory,
|
|
11524
12623
|
score: item.score,
|
|
@@ -11716,35 +12815,65 @@ function createRetrieval() {
|
|
|
11716
12815
|
return new SmartVectorRetrieval;
|
|
11717
12816
|
}
|
|
11718
12817
|
|
|
12818
|
+
// src/types/memory.ts
|
|
12819
|
+
var MEMORY_TYPE_EMOJI = {
|
|
12820
|
+
breakthrough: "\uD83D\uDCA1",
|
|
12821
|
+
decision: "⚖️",
|
|
12822
|
+
personal: "\uD83D\uDC9C",
|
|
12823
|
+
technical: "\uD83D\uDD27",
|
|
12824
|
+
technical_state: "\uD83D\uDCCD",
|
|
12825
|
+
unresolved: "❓",
|
|
12826
|
+
preference: "⚙️",
|
|
12827
|
+
workflow: "\uD83D\uDD04",
|
|
12828
|
+
architectural: "\uD83C\uDFD7️",
|
|
12829
|
+
debugging: "\uD83D\uDC1B",
|
|
12830
|
+
philosophy: "\uD83C\uDF00",
|
|
12831
|
+
todo: "\uD83C\uDFAF",
|
|
12832
|
+
implementation: "⚡",
|
|
12833
|
+
problem_solution: "✅",
|
|
12834
|
+
project_context: "\uD83D\uDCE6",
|
|
12835
|
+
milestone: "\uD83C\uDFC6",
|
|
12836
|
+
general: "\uD83D\uDCDD"
|
|
12837
|
+
};
|
|
12838
|
+
function getMemoryEmoji(contextType) {
|
|
12839
|
+
return MEMORY_TYPE_EMOJI[contextType.toLowerCase()] ?? "\uD83D\uDCDD";
|
|
12840
|
+
}
|
|
12841
|
+
|
|
11719
12842
|
// src/core/engine.ts
|
|
11720
12843
|
class MemoryEngine {
|
|
11721
12844
|
_config;
|
|
11722
12845
|
_stores = new Map;
|
|
11723
12846
|
_retrieval;
|
|
12847
|
+
_sessionMetadata = new Map;
|
|
11724
12848
|
constructor(config = {}) {
|
|
11725
12849
|
this._config = {
|
|
11726
12850
|
storageMode: config.storageMode ?? "central",
|
|
11727
|
-
centralPath: config.centralPath ??
|
|
12851
|
+
centralPath: config.centralPath ?? join2(homedir2(), ".local", "share", "memory"),
|
|
11728
12852
|
localFolder: config.localFolder ?? ".memory",
|
|
11729
12853
|
maxMemories: config.maxMemories ?? 5,
|
|
11730
12854
|
embedder: config.embedder
|
|
11731
12855
|
};
|
|
11732
12856
|
this._retrieval = createRetrieval();
|
|
11733
12857
|
}
|
|
12858
|
+
_getSessionMetadata(sessionId, projectId) {
|
|
12859
|
+
if (!this._sessionMetadata.has(sessionId)) {
|
|
12860
|
+
this._sessionMetadata.set(sessionId, {
|
|
12861
|
+
message_count: 0,
|
|
12862
|
+
started_at: Date.now(),
|
|
12863
|
+
project_id: projectId,
|
|
12864
|
+
injected_memories: new Set
|
|
12865
|
+
});
|
|
12866
|
+
}
|
|
12867
|
+
return this._sessionMetadata.get(sessionId);
|
|
12868
|
+
}
|
|
11734
12869
|
async _getStore(projectId, projectPath) {
|
|
11735
12870
|
const key = this._config.storageMode === "local" && projectPath ? projectPath : projectId;
|
|
11736
|
-
console.log(`\uD83C\uDFEA [DEBUG] _getStore called:`);
|
|
11737
|
-
console.log(` projectId: ${projectId}`);
|
|
11738
|
-
console.log(` projectPath: ${projectPath}`);
|
|
11739
|
-
console.log(` storageMode: ${this._config.storageMode}`);
|
|
11740
|
-
console.log(` cache key: ${key}`);
|
|
11741
|
-
console.log(` cached: ${this._stores.has(key)}`);
|
|
11742
12871
|
if (this._stores.has(key)) {
|
|
11743
12872
|
return this._stores.get(key);
|
|
11744
12873
|
}
|
|
11745
12874
|
let basePath;
|
|
11746
12875
|
if (this._config.storageMode === "local" && projectPath) {
|
|
11747
|
-
basePath =
|
|
12876
|
+
basePath = join2(projectPath, this._config.localFolder);
|
|
11748
12877
|
} else {
|
|
11749
12878
|
basePath = this._config.centralPath;
|
|
11750
12879
|
}
|
|
@@ -11773,10 +12902,16 @@ class MemoryEngine {
|
|
|
11773
12902
|
if (!currentMessage.trim()) {
|
|
11774
12903
|
return { memories: [], formatted: "" };
|
|
11775
12904
|
}
|
|
12905
|
+
const sessionMeta = this._getSessionMetadata(sessionId, projectId);
|
|
12906
|
+
const injectedIds = sessionMeta.injected_memories;
|
|
11776
12907
|
const allMemories = await store.getAllMemories(projectId);
|
|
11777
12908
|
if (!allMemories.length) {
|
|
11778
12909
|
return { memories: [], formatted: "" };
|
|
11779
12910
|
}
|
|
12911
|
+
const candidateMemories = allMemories.filter((m) => !injectedIds.has(m.id));
|
|
12912
|
+
if (!candidateMemories.length) {
|
|
12913
|
+
return { memories: [], formatted: "" };
|
|
12914
|
+
}
|
|
11780
12915
|
let queryEmbedding;
|
|
11781
12916
|
if (this._config.embedder) {
|
|
11782
12917
|
queryEmbedding = await this._config.embedder(currentMessage);
|
|
@@ -11786,7 +12921,10 @@ class MemoryEngine {
|
|
|
11786
12921
|
project_id: projectId,
|
|
11787
12922
|
message_count: messageCount
|
|
11788
12923
|
};
|
|
11789
|
-
const relevantMemories = this._retrieval.retrieveRelevantMemories(
|
|
12924
|
+
const relevantMemories = this._retrieval.retrieveRelevantMemories(candidateMemories, currentMessage, queryEmbedding ?? new Float32Array(384), sessionContext, maxMemories, injectedIds.size);
|
|
12925
|
+
for (const memory of relevantMemories) {
|
|
12926
|
+
injectedIds.add(memory.id);
|
|
12927
|
+
}
|
|
11790
12928
|
return {
|
|
11791
12929
|
memories: relevantMemories,
|
|
11792
12930
|
formatted: this._formatMemories(relevantMemories)
|
|
@@ -11831,12 +12969,32 @@ class MemoryEngine {
|
|
|
11831
12969
|
const timeSince = Date.now() - summary.created_at;
|
|
11832
12970
|
temporalContext = this._formatTimeSince(timeSince);
|
|
11833
12971
|
}
|
|
12972
|
+
const currentDatetime = this._formatCurrentDatetime();
|
|
12973
|
+
const sessionNumber = stats.totalSessions + 1;
|
|
11834
12974
|
return {
|
|
11835
12975
|
temporal_context: temporalContext,
|
|
12976
|
+
current_datetime: currentDatetime,
|
|
12977
|
+
session_number: sessionNumber,
|
|
11836
12978
|
session_summary: summary?.summary,
|
|
11837
12979
|
project_status: snapshot ? this._formatSnapshot(snapshot) : undefined
|
|
11838
12980
|
};
|
|
11839
12981
|
}
|
|
12982
|
+
_formatCurrentDatetime() {
|
|
12983
|
+
const now = new Date;
|
|
12984
|
+
const dayOfWeek = now.toLocaleDateString("en-US", { weekday: "long" });
|
|
12985
|
+
const fullDate = now.toLocaleDateString("en-US", {
|
|
12986
|
+
month: "long",
|
|
12987
|
+
day: "numeric",
|
|
12988
|
+
year: "numeric"
|
|
12989
|
+
});
|
|
12990
|
+
const time = now.toLocaleTimeString("en-US", {
|
|
12991
|
+
hour: "numeric",
|
|
12992
|
+
minute: "2-digit",
|
|
12993
|
+
hour12: true
|
|
12994
|
+
});
|
|
12995
|
+
const timezone = now.toLocaleTimeString("en-US", { timeZoneName: "short" }).split(" ").pop();
|
|
12996
|
+
return `${dayOfWeek}, ${fullDate} • ${time} • ${timezone}`;
|
|
12997
|
+
}
|
|
11840
12998
|
_formatTimeSince(ms) {
|
|
11841
12999
|
const minutes = Math.floor(ms / 60000);
|
|
11842
13000
|
const hours = Math.floor(minutes / 60);
|
|
@@ -11869,9 +13027,8 @@ class MemoryEngine {
|
|
|
11869
13027
|
}
|
|
11870
13028
|
_formatPrimer(primer) {
|
|
11871
13029
|
const parts = ["# Continuing Session"];
|
|
11872
|
-
|
|
11873
|
-
|
|
11874
|
-
}
|
|
13030
|
+
parts.push(`*Session #${primer.session_number}${primer.temporal_context ? ` • ${primer.temporal_context}` : ""}*`);
|
|
13031
|
+
parts.push(`\uD83D\uDCC5 ${primer.current_datetime}`);
|
|
11875
13032
|
if (primer.session_summary) {
|
|
11876
13033
|
parts.push(`
|
|
11877
13034
|
**Previous session**: ${primer.session_summary}`);
|
|
@@ -11881,6 +13038,8 @@ class MemoryEngine {
|
|
|
11881
13038
|
**Project status**: ${primer.project_status}`);
|
|
11882
13039
|
}
|
|
11883
13040
|
parts.push(`
|
|
13041
|
+
**Memory types**: \uD83D\uDCA1breakthrough ⚖️decision \uD83D\uDC9Cpersonal \uD83D\uDD27technical \uD83D\uDCCDstate ❓unresolved ⚙️preference \uD83D\uDD04workflow \uD83C\uDFD7️architecture \uD83D\uDC1Bdebug \uD83C\uDF00philosophy \uD83C\uDFAFtodo ⚡impl ✅solved \uD83D\uDCE6project \uD83C\uDFC6milestone`);
|
|
13042
|
+
parts.push(`
|
|
11884
13043
|
*Memories will surface naturally as we converse.*`);
|
|
11885
13044
|
return parts.join(`
|
|
11886
13045
|
`);
|
|
@@ -11894,8 +13053,8 @@ class MemoryEngine {
|
|
|
11894
13053
|
for (const memory of memories) {
|
|
11895
13054
|
const tags = memory.semantic_tags?.join(", ") || "";
|
|
11896
13055
|
const importance = memory.importance_weight?.toFixed(1) || "0.5";
|
|
11897
|
-
const
|
|
11898
|
-
parts.push(`[${
|
|
13056
|
+
const emoji = getMemoryEmoji(memory.context_type || "general");
|
|
13057
|
+
parts.push(`[${emoji} • ${importance}] [${tags}] ${memory.content}`);
|
|
11899
13058
|
}
|
|
11900
13059
|
return parts.join(`
|
|
11901
13060
|
`);
|
|
@@ -11912,14 +13071,14 @@ function createEngine(config) {
|
|
|
11912
13071
|
}
|
|
11913
13072
|
// src/core/curator.ts
|
|
11914
13073
|
import { homedir as homedir3 } from "os";
|
|
11915
|
-
import { join as
|
|
13074
|
+
import { join as join3 } from "path";
|
|
11916
13075
|
import { existsSync } from "fs";
|
|
11917
13076
|
function getClaudeCommand() {
|
|
11918
13077
|
const envCommand = process.env.CURATOR_COMMAND;
|
|
11919
13078
|
if (envCommand) {
|
|
11920
13079
|
return envCommand;
|
|
11921
13080
|
}
|
|
11922
|
-
const claudeLocal =
|
|
13081
|
+
const claudeLocal = join3(homedir3(), ".claude", "local", "claude");
|
|
11923
13082
|
if (existsSync(claudeLocal)) {
|
|
11924
13083
|
return claudeLocal;
|
|
11925
13084
|
}
|
|
@@ -11935,7 +13094,6 @@ class Curator {
|
|
|
11935
13094
|
cliCommand,
|
|
11936
13095
|
cliType: config.cliType ?? "claude-code"
|
|
11937
13096
|
};
|
|
11938
|
-
console.log(`\uD83E\uDDE0 Curator initialized with CLI: ${cliCommand}`);
|
|
11939
13097
|
}
|
|
11940
13098
|
buildCurationPrompt(triggerType = "session_end") {
|
|
11941
13099
|
return `You have just had a conversation. As this session is ending (${triggerType}), please curate memories for the Claude Tools Memory System.
|
|
@@ -12013,8 +13171,9 @@ Return ONLY this JSON structure:
|
|
|
12013
13171
|
"interaction_tone": "The tone/style of interaction (e.g., professional and focused, warm collaborative friendship, mentor-student dynamic, casual technical discussion, or null if neutral)",
|
|
12014
13172
|
"project_snapshot": {
|
|
12015
13173
|
"current_phase": "Current state (if applicable)",
|
|
12016
|
-
"recent_achievements": "What was accomplished (if applicable)",
|
|
12017
|
-
"active_challenges": "What remains (if applicable)"
|
|
13174
|
+
"recent_achievements": ["What was accomplished (if applicable)"],
|
|
13175
|
+
"active_challenges": ["What remains (if applicable)"],
|
|
13176
|
+
"next_steps": ["Planned next actions (if applicable)"]
|
|
12018
13177
|
},
|
|
12019
13178
|
"memories": [
|
|
12020
13179
|
{
|
|
@@ -12057,8 +13216,7 @@ Return ONLY this JSON structure:
|
|
|
12057
13216
|
} : undefined,
|
|
12058
13217
|
memories: this._parseMemories(data.memories ?? [])
|
|
12059
13218
|
};
|
|
12060
|
-
} catch
|
|
12061
|
-
console.error("Failed to parse curation response:", error);
|
|
13219
|
+
} catch {
|
|
12062
13220
|
return {
|
|
12063
13221
|
session_summary: "",
|
|
12064
13222
|
memories: []
|
|
@@ -12128,25 +13286,21 @@ ${prompt}`
|
|
|
12128
13286
|
}
|
|
12129
13287
|
return this.parseCurationResponse(content.text);
|
|
12130
13288
|
}
|
|
12131
|
-
async curateWithCLI(sessionId, triggerType = "session_end", cwd) {
|
|
13289
|
+
async curateWithCLI(sessionId, triggerType = "session_end", cwd, cliTypeOverride) {
|
|
13290
|
+
const type = cliTypeOverride ?? this._config.cliType;
|
|
12132
13291
|
const systemPrompt = this.buildCurationPrompt(triggerType);
|
|
12133
13292
|
const userMessage = "This session has ended. Please curate the memories from our conversation according to the instructions in your system prompt. Return ONLY the JSON structure.";
|
|
12134
13293
|
const args = [];
|
|
12135
|
-
|
|
13294
|
+
let command = this._config.cliCommand;
|
|
13295
|
+
if (type === "claude-code") {
|
|
12136
13296
|
args.push("--resume", sessionId, "-p", userMessage, "--append-system-prompt", systemPrompt, "--output-format", "json", "--max-turns", "1");
|
|
12137
13297
|
} else {
|
|
13298
|
+
command = "gemini";
|
|
12138
13299
|
args.push("--resume", sessionId, "-p", `${systemPrompt}
|
|
12139
13300
|
|
|
12140
13301
|
${userMessage}`, "--output-format", "json");
|
|
12141
13302
|
}
|
|
12142
|
-
|
|
12143
|
-
\uD83D\uDCCB Executing CLI command:`);
|
|
12144
|
-
console.log(` Command: ${this._config.cliCommand}`);
|
|
12145
|
-
console.log(` Args: --resume ${sessionId} -p [user_message] --append-system-prompt [curation_instructions] --output-format json --max-turns 1`);
|
|
12146
|
-
console.log(` CWD: ${cwd || "not set"}`);
|
|
12147
|
-
console.log(` User message: "${userMessage.slice(0, 50)}..."`);
|
|
12148
|
-
console.log(` System prompt length: ${systemPrompt.length} chars`);
|
|
12149
|
-
const proc = Bun.spawn([this._config.cliCommand, ...args], {
|
|
13303
|
+
const proc = Bun.spawn([command, ...args], {
|
|
12150
13304
|
cwd,
|
|
12151
13305
|
env: {
|
|
12152
13306
|
...process.env,
|
|
@@ -12159,67 +13313,29 @@ ${userMessage}`, "--output-format", "json");
|
|
|
12159
13313
|
new Response(proc.stderr).text()
|
|
12160
13314
|
]);
|
|
12161
13315
|
const exitCode = await proc.exited;
|
|
12162
|
-
console.log(`
|
|
12163
|
-
\uD83D\uDCE4 CLI Response:`);
|
|
12164
|
-
console.log(` Exit code: ${exitCode}`);
|
|
12165
|
-
console.log(` Stdout length: ${stdout.length} chars`);
|
|
12166
|
-
console.log(` Stderr length: ${stderr.length} chars`);
|
|
12167
|
-
if (stderr) {
|
|
12168
|
-
console.log(`
|
|
12169
|
-
⚠️ Stderr output:`);
|
|
12170
|
-
console.log(stderr.slice(0, 1000));
|
|
12171
|
-
}
|
|
12172
|
-
if (stdout) {
|
|
12173
|
-
console.log(`
|
|
12174
|
-
\uD83D\uDCE5 Stdout output (first 500 chars):`);
|
|
12175
|
-
console.log(stdout.slice(0, 500));
|
|
12176
|
-
}
|
|
12177
13316
|
if (exitCode !== 0) {
|
|
12178
|
-
console.error(`
|
|
12179
|
-
❌ CLI exited with code ${exitCode}`);
|
|
12180
13317
|
return { session_summary: "", memories: [] };
|
|
12181
13318
|
}
|
|
12182
13319
|
try {
|
|
12183
13320
|
const cliOutput = JSON.parse(stdout);
|
|
12184
13321
|
if (cliOutput.type === "error" || cliOutput.is_error === true) {
|
|
12185
|
-
console.log(`
|
|
12186
|
-
❌ CLI returned error:`);
|
|
12187
|
-
console.log(` Type: ${cliOutput.type}`);
|
|
12188
|
-
console.log(` Message: ${cliOutput.message || cliOutput.error || "Unknown error"}`);
|
|
12189
13322
|
return { session_summary: "", memories: [] };
|
|
12190
13323
|
}
|
|
12191
13324
|
let aiResponse = "";
|
|
12192
13325
|
if (typeof cliOutput.result === "string") {
|
|
12193
13326
|
aiResponse = cliOutput.result;
|
|
12194
|
-
console.log(`
|
|
12195
|
-
\uD83D\uDCE6 Extracted result from CLI wrapper (${aiResponse.length} chars)`);
|
|
12196
13327
|
} else {
|
|
12197
|
-
console.log(`
|
|
12198
|
-
⚠️ No result field in CLI output`);
|
|
12199
|
-
console.log(` Keys: ${Object.keys(cliOutput).join(", ")}`);
|
|
12200
13328
|
return { session_summary: "", memories: [] };
|
|
12201
13329
|
}
|
|
12202
13330
|
const codeBlockMatch = aiResponse.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
12203
13331
|
if (codeBlockMatch) {
|
|
12204
13332
|
aiResponse = codeBlockMatch[1].trim();
|
|
12205
|
-
console.log(`\uD83D\uDCDD Extracted JSON from markdown code block`);
|
|
12206
13333
|
}
|
|
12207
13334
|
const jsonMatch = aiResponse.match(/\{[\s\S]*\}/)?.[0];
|
|
12208
13335
|
if (jsonMatch) {
|
|
12209
|
-
|
|
12210
|
-
const result = this.parseCurationResponse(jsonMatch);
|
|
12211
|
-
console.log(` Parsed ${result.memories.length} memories`);
|
|
12212
|
-
return result;
|
|
12213
|
-
} else {
|
|
12214
|
-
console.log(`
|
|
12215
|
-
⚠️ No JSON object found in AI response`);
|
|
12216
|
-
console.log(` Response preview: ${aiResponse.slice(0, 200)}...`);
|
|
13336
|
+
return this.parseCurationResponse(jsonMatch);
|
|
12217
13337
|
}
|
|
12218
|
-
} catch
|
|
12219
|
-
console.error(`
|
|
12220
|
-
❌ Failed to parse CLI output:`, error);
|
|
12221
|
-
console.log(` Raw stdout (first 500 chars): ${stdout.slice(0, 500)}`);
|
|
12222
|
-
}
|
|
13338
|
+
} catch {}
|
|
12223
13339
|
return { session_summary: "", memories: [] };
|
|
12224
13340
|
}
|
|
12225
13341
|
}
|