@rlabs-inc/memory 0.3.3 → 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/package.json +1 -1
- 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/{gemini-hooks → hooks/gemini}/curation.ts +0 -0
- /package/{gemini-hooks → hooks/gemini}/session-start.ts +0 -0
- /package/{gemini-hooks → hooks/gemini}/user-prompt.ts +0 -0
package/dist/index.js
CHANGED
|
@@ -225,10 +225,10 @@ var require_lib = __commonJS((exports2, module2) => {
|
|
|
225
225
|
|
|
226
226
|
// node_modules/whatwg-url/lib/utils.js
|
|
227
227
|
var require_utils = __commonJS((exports2, module2) => {
|
|
228
|
-
module2.exports.mixin = function mixin(target,
|
|
229
|
-
const keys = Object.getOwnPropertyNames(
|
|
228
|
+
module2.exports.mixin = function mixin(target, source2) {
|
|
229
|
+
const keys = Object.getOwnPropertyNames(source2);
|
|
230
230
|
for (let i = 0;i < keys.length; ++i) {
|
|
231
|
-
Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(
|
|
231
|
+
Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(source2, keys[i]));
|
|
232
232
|
}
|
|
233
233
|
};
|
|
234
234
|
module2.exports.wrapperSymbol = Symbol("wrapper");
|
|
@@ -2548,8 +2548,8 @@ var require_lib2 = __commonJS((exports2, module2) => {
|
|
|
2548
2548
|
function isRequest(input) {
|
|
2549
2549
|
return typeof input === "object" && typeof input[INTERNALS$2] === "object";
|
|
2550
2550
|
}
|
|
2551
|
-
function isAbortSignal(
|
|
2552
|
-
const proto =
|
|
2551
|
+
function isAbortSignal(signal2) {
|
|
2552
|
+
const proto = signal2 && typeof signal2 === "object" && Object.getPrototypeOf(signal2);
|
|
2553
2553
|
return !!(proto && proto.constructor.name === "AbortSignal");
|
|
2554
2554
|
}
|
|
2555
2555
|
|
|
@@ -2584,10 +2584,10 @@ var require_lib2 = __commonJS((exports2, module2) => {
|
|
|
2584
2584
|
headers.append("Content-Type", contentType);
|
|
2585
2585
|
}
|
|
2586
2586
|
}
|
|
2587
|
-
let
|
|
2587
|
+
let signal2 = isRequest(input) ? input.signal : null;
|
|
2588
2588
|
if ("signal" in init)
|
|
2589
|
-
|
|
2590
|
-
if (
|
|
2589
|
+
signal2 = init.signal;
|
|
2590
|
+
if (signal2 != null && !isAbortSignal(signal2)) {
|
|
2591
2591
|
throw new TypeError("Expected signal to be an instanceof AbortSignal");
|
|
2592
2592
|
}
|
|
2593
2593
|
this[INTERNALS$2] = {
|
|
@@ -2595,7 +2595,7 @@ var require_lib2 = __commonJS((exports2, module2) => {
|
|
|
2595
2595
|
redirect: init.redirect || input.redirect || "follow",
|
|
2596
2596
|
headers,
|
|
2597
2597
|
parsedURL,
|
|
2598
|
-
signal
|
|
2598
|
+
signal: signal2
|
|
2599
2599
|
};
|
|
2600
2600
|
this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20;
|
|
2601
2601
|
this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true;
|
|
@@ -2710,7 +2710,7 @@ var require_lib2 = __commonJS((exports2, module2) => {
|
|
|
2710
2710
|
const request = new Request2(url, opts);
|
|
2711
2711
|
const options = getNodeRequestOptions(request);
|
|
2712
2712
|
const send = (options.protocol === "https:" ? https : http).request;
|
|
2713
|
-
const
|
|
2713
|
+
const signal2 = request.signal;
|
|
2714
2714
|
let response = null;
|
|
2715
2715
|
const abort = function abort() {
|
|
2716
2716
|
let error = new AbortError("The user aborted a request.");
|
|
@@ -2722,7 +2722,7 @@ var require_lib2 = __commonJS((exports2, module2) => {
|
|
|
2722
2722
|
return;
|
|
2723
2723
|
response.body.emit("error", error);
|
|
2724
2724
|
};
|
|
2725
|
-
if (
|
|
2725
|
+
if (signal2 && signal2.aborted) {
|
|
2726
2726
|
abort();
|
|
2727
2727
|
return;
|
|
2728
2728
|
}
|
|
@@ -2732,13 +2732,13 @@ var require_lib2 = __commonJS((exports2, module2) => {
|
|
|
2732
2732
|
};
|
|
2733
2733
|
const req = send(options);
|
|
2734
2734
|
let reqTimeout;
|
|
2735
|
-
if (
|
|
2736
|
-
|
|
2735
|
+
if (signal2) {
|
|
2736
|
+
signal2.addEventListener("abort", abortAndFinalize);
|
|
2737
2737
|
}
|
|
2738
2738
|
function finalize() {
|
|
2739
2739
|
req.abort();
|
|
2740
|
-
if (
|
|
2741
|
-
|
|
2740
|
+
if (signal2)
|
|
2741
|
+
signal2.removeEventListener("abort", abortAndFinalize);
|
|
2742
2742
|
clearTimeout(reqTimeout);
|
|
2743
2743
|
}
|
|
2744
2744
|
if (request.timeout) {
|
|
@@ -2757,7 +2757,7 @@ var require_lib2 = __commonJS((exports2, module2) => {
|
|
|
2757
2757
|
finalize();
|
|
2758
2758
|
});
|
|
2759
2759
|
fixResponseChunkedTransferBadEnding(req, function(err) {
|
|
2760
|
-
if (
|
|
2760
|
+
if (signal2 && signal2.aborted) {
|
|
2761
2761
|
return;
|
|
2762
2762
|
}
|
|
2763
2763
|
if (response && response.body) {
|
|
@@ -2768,7 +2768,7 @@ var require_lib2 = __commonJS((exports2, module2) => {
|
|
|
2768
2768
|
req.on("socket", function(s) {
|
|
2769
2769
|
s.addListener("close", function(hadError) {
|
|
2770
2770
|
const hasDataListener = s.listenerCount("data") > 0;
|
|
2771
|
-
if (response && hasDataListener && !hadError && !(
|
|
2771
|
+
if (response && hasDataListener && !hadError && !(signal2 && signal2.aborted)) {
|
|
2772
2772
|
const err = new Error("Premature close");
|
|
2773
2773
|
err.code = "ERR_STREAM_PREMATURE_CLOSE";
|
|
2774
2774
|
response.body.emit("error", err);
|
|
@@ -2847,8 +2847,8 @@ var require_lib2 = __commonJS((exports2, module2) => {
|
|
|
2847
2847
|
}
|
|
2848
2848
|
}
|
|
2849
2849
|
res.once("end", function() {
|
|
2850
|
-
if (
|
|
2851
|
-
|
|
2850
|
+
if (signal2)
|
|
2851
|
+
signal2.removeEventListener("abort", abortAndFinalize);
|
|
2852
2852
|
});
|
|
2853
2853
|
let body = res.pipe(new PassThrough$1);
|
|
2854
2854
|
const response_options = {
|
|
@@ -5018,20 +5018,20 @@ var init_blobHelpers = __esm(() => {
|
|
|
5018
5018
|
});
|
|
5019
5019
|
|
|
5020
5020
|
// node_modules/formdata-node/lib/esm/Blob.js
|
|
5021
|
-
var __classPrivateFieldGet = function(receiver,
|
|
5021
|
+
var __classPrivateFieldGet = function(receiver, state, kind2, f2) {
|
|
5022
5022
|
if (kind2 === "a" && !f2)
|
|
5023
5023
|
throw new TypeError("Private accessor was defined without a getter");
|
|
5024
|
-
if (typeof
|
|
5024
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
5025
5025
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5026
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
5027
|
-
}, __classPrivateFieldSet = function(receiver,
|
|
5026
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
5027
|
+
}, __classPrivateFieldSet = function(receiver, state, value, kind2, f2) {
|
|
5028
5028
|
if (kind2 === "m")
|
|
5029
5029
|
throw new TypeError("Private method is not writable");
|
|
5030
5030
|
if (kind2 === "a" && !f2)
|
|
5031
5031
|
throw new TypeError("Private accessor was defined without a setter");
|
|
5032
|
-
if (typeof
|
|
5032
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
5033
5033
|
throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5034
|
-
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value :
|
|
5034
|
+
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value : state.set(receiver, value), value;
|
|
5035
5035
|
}, _Blob_parts, _Blob_type, _Blob_size, Blob2;
|
|
5036
5036
|
var init_Blob = __esm(() => {
|
|
5037
5037
|
init_ponyfill();
|
|
@@ -5132,20 +5132,20 @@ var init_Blob = __esm(() => {
|
|
|
5132
5132
|
});
|
|
5133
5133
|
|
|
5134
5134
|
// node_modules/formdata-node/lib/esm/File.js
|
|
5135
|
-
var __classPrivateFieldSet2 = function(receiver,
|
|
5135
|
+
var __classPrivateFieldSet2 = function(receiver, state, value, kind2, f2) {
|
|
5136
5136
|
if (kind2 === "m")
|
|
5137
5137
|
throw new TypeError("Private method is not writable");
|
|
5138
5138
|
if (kind2 === "a" && !f2)
|
|
5139
5139
|
throw new TypeError("Private accessor was defined without a setter");
|
|
5140
|
-
if (typeof
|
|
5140
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
5141
5141
|
throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5142
|
-
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value :
|
|
5143
|
-
}, __classPrivateFieldGet2 = function(receiver,
|
|
5142
|
+
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value : state.set(receiver, value), value;
|
|
5143
|
+
}, __classPrivateFieldGet2 = function(receiver, state, kind2, f2) {
|
|
5144
5144
|
if (kind2 === "a" && !f2)
|
|
5145
5145
|
throw new TypeError("Private accessor was defined without a getter");
|
|
5146
|
-
if (typeof
|
|
5146
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
5147
5147
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5148
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
5148
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
5149
5149
|
}, _File_name, _File_lastModified, File2;
|
|
5150
5150
|
var init_File = __esm(() => {
|
|
5151
5151
|
init_Blob();
|
|
@@ -5194,22 +5194,22 @@ var init_isBlob = __esm(() => {
|
|
|
5194
5194
|
});
|
|
5195
5195
|
|
|
5196
5196
|
// node_modules/formdata-node/lib/esm/deprecateConstructorEntries.js
|
|
5197
|
-
var
|
|
5197
|
+
var import_util2, deprecateConstructorEntries;
|
|
5198
5198
|
var init_deprecateConstructorEntries = __esm(() => {
|
|
5199
|
-
|
|
5200
|
-
deprecateConstructorEntries =
|
|
5199
|
+
import_util2 = require("util");
|
|
5200
|
+
deprecateConstructorEntries = import_util2.deprecate(() => {}, 'Constructor "entries" argument is not spec-compliant ' + "and will be removed in next major release.");
|
|
5201
5201
|
});
|
|
5202
5202
|
|
|
5203
5203
|
// node_modules/formdata-node/lib/esm/FormData.js
|
|
5204
|
-
var
|
|
5204
|
+
var import_util3, __classPrivateFieldGet3 = function(receiver, state, kind2, f2) {
|
|
5205
5205
|
if (kind2 === "a" && !f2)
|
|
5206
5206
|
throw new TypeError("Private accessor was defined without a getter");
|
|
5207
|
-
if (typeof
|
|
5207
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
5208
5208
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5209
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
5209
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
5210
5210
|
}, _FormData_instances, _FormData_entries, _FormData_setEntry, FormData2;
|
|
5211
5211
|
var init_FormData = __esm(() => {
|
|
5212
|
-
|
|
5212
|
+
import_util3 = require("util");
|
|
5213
5213
|
init_File();
|
|
5214
5214
|
init_isFile();
|
|
5215
5215
|
init_isBlob();
|
|
@@ -5322,7 +5322,7 @@ var init_FormData = __esm(() => {
|
|
|
5322
5322
|
get [Symbol.toStringTag]() {
|
|
5323
5323
|
return "FormData";
|
|
5324
5324
|
}
|
|
5325
|
-
[
|
|
5325
|
+
[import_util3.inspect.custom]() {
|
|
5326
5326
|
return this[Symbol.toStringTag];
|
|
5327
5327
|
}
|
|
5328
5328
|
};
|
|
@@ -6271,17 +6271,17 @@ var require_abort_controller = __commonJS((exports2, module2) => {
|
|
|
6271
6271
|
}
|
|
6272
6272
|
eventTargetShim.defineEventAttribute(AbortSignal.prototype, "abort");
|
|
6273
6273
|
function createAbortSignal() {
|
|
6274
|
-
const
|
|
6275
|
-
eventTargetShim.EventTarget.call(
|
|
6276
|
-
abortedFlags.set(
|
|
6277
|
-
return
|
|
6274
|
+
const signal2 = Object.create(AbortSignal.prototype);
|
|
6275
|
+
eventTargetShim.EventTarget.call(signal2);
|
|
6276
|
+
abortedFlags.set(signal2, false);
|
|
6277
|
+
return signal2;
|
|
6278
6278
|
}
|
|
6279
|
-
function abortSignal(
|
|
6280
|
-
if (abortedFlags.get(
|
|
6279
|
+
function abortSignal(signal2) {
|
|
6280
|
+
if (abortedFlags.get(signal2) !== false) {
|
|
6281
6281
|
return;
|
|
6282
6282
|
}
|
|
6283
|
-
abortedFlags.set(
|
|
6284
|
-
|
|
6283
|
+
abortedFlags.set(signal2, true);
|
|
6284
|
+
signal2.dispatchEvent({ type: "abort" });
|
|
6285
6285
|
}
|
|
6286
6286
|
var abortedFlags = new WeakMap;
|
|
6287
6287
|
Object.defineProperties(AbortSignal.prototype, {
|
|
@@ -6307,11 +6307,11 @@ var require_abort_controller = __commonJS((exports2, module2) => {
|
|
|
6307
6307
|
}
|
|
6308
6308
|
var signals = new WeakMap;
|
|
6309
6309
|
function getSignal(controller) {
|
|
6310
|
-
const
|
|
6311
|
-
if (
|
|
6310
|
+
const signal2 = signals.get(controller);
|
|
6311
|
+
if (signal2 == null) {
|
|
6312
6312
|
throw new TypeError(`Expected 'this' to be an 'AbortController' object, but got ${controller === null ? "null" : typeof controller}`);
|
|
6313
6313
|
}
|
|
6314
|
-
return
|
|
6314
|
+
return signal2;
|
|
6315
6315
|
}
|
|
6316
6316
|
Object.defineProperties(AbortController2.prototype, {
|
|
6317
6317
|
signal: { enumerable: true },
|
|
@@ -6401,20 +6401,20 @@ var init_isFormData = __esm(() => {
|
|
|
6401
6401
|
});
|
|
6402
6402
|
|
|
6403
6403
|
// node_modules/form-data-encoder/lib/esm/FormDataEncoder.js
|
|
6404
|
-
var __classPrivateFieldSet3 = function(receiver,
|
|
6404
|
+
var __classPrivateFieldSet3 = function(receiver, state, value, kind2, f2) {
|
|
6405
6405
|
if (kind2 === "m")
|
|
6406
6406
|
throw new TypeError("Private method is not writable");
|
|
6407
6407
|
if (kind2 === "a" && !f2)
|
|
6408
6408
|
throw new TypeError("Private accessor was defined without a setter");
|
|
6409
|
-
if (typeof
|
|
6409
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
6410
6410
|
throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6411
|
-
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value :
|
|
6412
|
-
}, __classPrivateFieldGet4 = function(receiver,
|
|
6411
|
+
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value : state.set(receiver, value), value;
|
|
6412
|
+
}, __classPrivateFieldGet4 = function(receiver, state, kind2, f2) {
|
|
6413
6413
|
if (kind2 === "a" && !f2)
|
|
6414
6414
|
throw new TypeError("Private accessor was defined without a getter");
|
|
6415
|
-
if (typeof
|
|
6415
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
6416
6416
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
6417
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
6417
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
6418
6418
|
}, _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;
|
|
6419
6419
|
var init_FormDataEncoder = __esm(() => {
|
|
6420
6420
|
init_createBoundary();
|
|
@@ -6614,24 +6614,24 @@ async function fileFromPath2(path, filenameOrOptions, options) {
|
|
|
6614
6614
|
const stats = await import_fs2.promises.stat(path);
|
|
6615
6615
|
return createFileFromPath(path, stats, filenameOrOptions, options);
|
|
6616
6616
|
}
|
|
6617
|
-
var import_fs2,
|
|
6617
|
+
var import_fs2, import_path3, import_node_domexception, __classPrivateFieldSet4 = function(receiver, state, value, kind2, f2) {
|
|
6618
6618
|
if (kind2 === "m")
|
|
6619
6619
|
throw new TypeError("Private method is not writable");
|
|
6620
6620
|
if (kind2 === "a" && !f2)
|
|
6621
6621
|
throw new TypeError("Private accessor was defined without a setter");
|
|
6622
|
-
if (typeof
|
|
6622
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
6623
6623
|
throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6624
|
-
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value :
|
|
6625
|
-
}, __classPrivateFieldGet5 = function(receiver,
|
|
6624
|
+
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value : state.set(receiver, value), value;
|
|
6625
|
+
}, __classPrivateFieldGet5 = function(receiver, state, kind2, f2) {
|
|
6626
6626
|
if (kind2 === "a" && !f2)
|
|
6627
6627
|
throw new TypeError("Private accessor was defined without a getter");
|
|
6628
|
-
if (typeof
|
|
6628
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
6629
6629
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
6630
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
6630
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
6631
6631
|
}, _FileFromPath_path, _FileFromPath_start, MESSAGE, FileFromPath;
|
|
6632
6632
|
var init_fileFromPath = __esm(() => {
|
|
6633
6633
|
import_fs2 = require("fs");
|
|
6634
|
-
|
|
6634
|
+
import_path3 = require("path");
|
|
6635
6635
|
import_node_domexception = __toESM(require_node_domexception());
|
|
6636
6636
|
init_File();
|
|
6637
6637
|
init_isPlainObject2();
|
|
@@ -6643,7 +6643,7 @@ var init_fileFromPath = __esm(() => {
|
|
|
6643
6643
|
_FileFromPath_start.set(this, undefined);
|
|
6644
6644
|
__classPrivateFieldSet4(this, _FileFromPath_path, input.path, "f");
|
|
6645
6645
|
__classPrivateFieldSet4(this, _FileFromPath_start, input.start || 0, "f");
|
|
6646
|
-
this.name =
|
|
6646
|
+
this.name = import_path3.basename(__classPrivateFieldGet5(this, _FileFromPath_path, "f"));
|
|
6647
6647
|
this.size = input.size;
|
|
6648
6648
|
this.lastModified = input.lastModified;
|
|
6649
6649
|
}
|
|
@@ -6931,20 +6931,20 @@ function findDoubleNewlineIndex(buffer) {
|
|
|
6931
6931
|
}
|
|
6932
6932
|
return -1;
|
|
6933
6933
|
}
|
|
6934
|
-
var __classPrivateFieldSet5 = function(receiver,
|
|
6934
|
+
var __classPrivateFieldSet5 = function(receiver, state, value, kind2, f2) {
|
|
6935
6935
|
if (kind2 === "m")
|
|
6936
6936
|
throw new TypeError("Private method is not writable");
|
|
6937
6937
|
if (kind2 === "a" && !f2)
|
|
6938
6938
|
throw new TypeError("Private accessor was defined without a setter");
|
|
6939
|
-
if (typeof
|
|
6939
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
6940
6940
|
throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6941
|
-
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value :
|
|
6942
|
-
}, __classPrivateFieldGet6 = function(receiver,
|
|
6941
|
+
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value : state.set(receiver, value), value;
|
|
6942
|
+
}, __classPrivateFieldGet6 = function(receiver, state, kind2, f2) {
|
|
6943
6943
|
if (kind2 === "a" && !f2)
|
|
6944
6944
|
throw new TypeError("Private accessor was defined without a getter");
|
|
6945
|
-
if (typeof
|
|
6945
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
6946
6946
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
6947
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
6947
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
6948
6948
|
}, _LineDecoder_carriageReturnIndex;
|
|
6949
6949
|
var init_line = __esm(() => {
|
|
6950
6950
|
init_error();
|
|
@@ -7525,9 +7525,9 @@ class APIClient {
|
|
|
7525
7525
|
}).join("&");
|
|
7526
7526
|
}
|
|
7527
7527
|
async fetchWithTimeout(url, init, ms, controller) {
|
|
7528
|
-
const { signal, ...options } = init || {};
|
|
7529
|
-
if (
|
|
7530
|
-
|
|
7528
|
+
const { signal: signal2, ...options } = init || {};
|
|
7529
|
+
if (signal2)
|
|
7530
|
+
signal2.addEventListener("abort", () => controller.abort());
|
|
7531
7531
|
const timeout = setTimeout(() => controller.abort(), ms);
|
|
7532
7532
|
const fetchOptions = {
|
|
7533
7533
|
signal: controller.signal,
|
|
@@ -7657,20 +7657,20 @@ function debug(action, ...args) {
|
|
|
7657
7657
|
console.log(`Anthropic:DEBUG:${action}`, ...args);
|
|
7658
7658
|
}
|
|
7659
7659
|
}
|
|
7660
|
-
var __classPrivateFieldSet6 = function(receiver,
|
|
7660
|
+
var __classPrivateFieldSet6 = function(receiver, state, value, kind2, f2) {
|
|
7661
7661
|
if (kind2 === "m")
|
|
7662
7662
|
throw new TypeError("Private method is not writable");
|
|
7663
7663
|
if (kind2 === "a" && !f2)
|
|
7664
7664
|
throw new TypeError("Private accessor was defined without a setter");
|
|
7665
|
-
if (typeof
|
|
7665
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
7666
7666
|
throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
7667
|
-
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value :
|
|
7668
|
-
}, __classPrivateFieldGet7 = function(receiver,
|
|
7667
|
+
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value : state.set(receiver, value), value;
|
|
7668
|
+
}, __classPrivateFieldGet7 = function(receiver, state, kind2, f2) {
|
|
7669
7669
|
if (kind2 === "a" && !f2)
|
|
7670
7670
|
throw new TypeError("Private accessor was defined without a getter");
|
|
7671
|
-
if (typeof
|
|
7671
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
7672
7672
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
7673
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
7673
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
7674
7674
|
}, _AbstractPage_client, APIPromise, AbstractPage, PagePromise, createResponseHeaders = (headers) => {
|
|
7675
7675
|
return new Proxy(Object.fromEntries(headers.entries()), {
|
|
7676
7676
|
get(target, name) {
|
|
@@ -8385,20 +8385,20 @@ var init_parser = () => {};
|
|
|
8385
8385
|
|
|
8386
8386
|
// node_modules/@anthropic-ai/sdk/lib/BetaMessageStream.mjs
|
|
8387
8387
|
function checkNever(x2) {}
|
|
8388
|
-
var __classPrivateFieldSet7 = function(receiver,
|
|
8388
|
+
var __classPrivateFieldSet7 = function(receiver, state, value, kind2, f2) {
|
|
8389
8389
|
if (kind2 === "m")
|
|
8390
8390
|
throw new TypeError("Private method is not writable");
|
|
8391
8391
|
if (kind2 === "a" && !f2)
|
|
8392
8392
|
throw new TypeError("Private accessor was defined without a setter");
|
|
8393
|
-
if (typeof
|
|
8393
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
8394
8394
|
throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
8395
|
-
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value :
|
|
8396
|
-
}, __classPrivateFieldGet8 = function(receiver,
|
|
8395
|
+
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value : state.set(receiver, value), value;
|
|
8396
|
+
}, __classPrivateFieldGet8 = function(receiver, state, kind2, f2) {
|
|
8397
8397
|
if (kind2 === "a" && !f2)
|
|
8398
8398
|
throw new TypeError("Private accessor was defined without a getter");
|
|
8399
|
-
if (typeof
|
|
8399
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
8400
8400
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
8401
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
8401
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
8402
8402
|
}, _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;
|
|
8403
8403
|
var init_BetaMessageStream = __esm(() => {
|
|
8404
8404
|
init_error();
|
|
@@ -8500,11 +8500,11 @@ var init_BetaMessageStream = __esm(() => {
|
|
|
8500
8500
|
}
|
|
8501
8501
|
}
|
|
8502
8502
|
async _createMessage(messages, params, options) {
|
|
8503
|
-
const
|
|
8504
|
-
if (
|
|
8505
|
-
if (
|
|
8503
|
+
const signal2 = options?.signal;
|
|
8504
|
+
if (signal2) {
|
|
8505
|
+
if (signal2.aborted)
|
|
8506
8506
|
this.controller.abort();
|
|
8507
|
-
|
|
8507
|
+
signal2.addEventListener("abort", () => this.controller.abort());
|
|
8508
8508
|
}
|
|
8509
8509
|
__classPrivateFieldGet8(this, _BetaMessageStream_instances, "m", _BetaMessageStream_beginRequest).call(this);
|
|
8510
8510
|
const { response, data: stream } = await messages.create({ ...params, stream: true }, { ...options, signal: this.controller.signal }).withResponse();
|
|
@@ -8618,11 +8618,11 @@ var init_BetaMessageStream = __esm(() => {
|
|
|
8618
8618
|
}
|
|
8619
8619
|
}
|
|
8620
8620
|
async _fromReadableStream(readableStream, options) {
|
|
8621
|
-
const
|
|
8622
|
-
if (
|
|
8623
|
-
if (
|
|
8621
|
+
const signal2 = options?.signal;
|
|
8622
|
+
if (signal2) {
|
|
8623
|
+
if (signal2.aborted)
|
|
8624
8624
|
this.controller.abort();
|
|
8625
|
-
|
|
8625
|
+
signal2.addEventListener("abort", () => this.controller.abort());
|
|
8626
8626
|
}
|
|
8627
8627
|
__classPrivateFieldGet8(this, _BetaMessageStream_instances, "m", _BetaMessageStream_beginRequest).call(this);
|
|
8628
8628
|
this._connected(null);
|
|
@@ -8993,20 +8993,20 @@ var init_batches2 = __esm(() => {
|
|
|
8993
8993
|
|
|
8994
8994
|
// node_modules/@anthropic-ai/sdk/lib/MessageStream.mjs
|
|
8995
8995
|
function checkNever2(x2) {}
|
|
8996
|
-
var __classPrivateFieldSet8 = function(receiver,
|
|
8996
|
+
var __classPrivateFieldSet8 = function(receiver, state, value, kind2, f2) {
|
|
8997
8997
|
if (kind2 === "m")
|
|
8998
8998
|
throw new TypeError("Private method is not writable");
|
|
8999
8999
|
if (kind2 === "a" && !f2)
|
|
9000
9000
|
throw new TypeError("Private accessor was defined without a setter");
|
|
9001
|
-
if (typeof
|
|
9001
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
9002
9002
|
throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
9003
|
-
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value :
|
|
9004
|
-
}, __classPrivateFieldGet9 = function(receiver,
|
|
9003
|
+
return kind2 === "a" ? f2.call(receiver, value) : f2 ? f2.value = value : state.set(receiver, value), value;
|
|
9004
|
+
}, __classPrivateFieldGet9 = function(receiver, state, kind2, f2) {
|
|
9005
9005
|
if (kind2 === "a" && !f2)
|
|
9006
9006
|
throw new TypeError("Private accessor was defined without a getter");
|
|
9007
|
-
if (typeof
|
|
9007
|
+
if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver))
|
|
9008
9008
|
throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
9009
|
-
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value :
|
|
9009
|
+
return kind2 === "m" ? f2 : kind2 === "a" ? f2.call(receiver) : f2 ? f2.value : state.get(receiver);
|
|
9010
9010
|
}, _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;
|
|
9011
9011
|
var init_MessageStream = __esm(() => {
|
|
9012
9012
|
init_error();
|
|
@@ -9108,11 +9108,11 @@ var init_MessageStream = __esm(() => {
|
|
|
9108
9108
|
}
|
|
9109
9109
|
}
|
|
9110
9110
|
async _createMessage(messages, params, options) {
|
|
9111
|
-
const
|
|
9112
|
-
if (
|
|
9113
|
-
if (
|
|
9111
|
+
const signal2 = options?.signal;
|
|
9112
|
+
if (signal2) {
|
|
9113
|
+
if (signal2.aborted)
|
|
9114
9114
|
this.controller.abort();
|
|
9115
|
-
|
|
9115
|
+
signal2.addEventListener("abort", () => this.controller.abort());
|
|
9116
9116
|
}
|
|
9117
9117
|
__classPrivateFieldGet9(this, _MessageStream_instances, "m", _MessageStream_beginRequest).call(this);
|
|
9118
9118
|
const { response, data: stream } = await messages.create({ ...params, stream: true }, { ...options, signal: this.controller.signal }).withResponse();
|
|
@@ -9226,11 +9226,11 @@ var init_MessageStream = __esm(() => {
|
|
|
9226
9226
|
}
|
|
9227
9227
|
}
|
|
9228
9228
|
async _fromReadableStream(readableStream, options) {
|
|
9229
|
-
const
|
|
9230
|
-
if (
|
|
9231
|
-
if (
|
|
9229
|
+
const signal2 = options?.signal;
|
|
9230
|
+
if (signal2) {
|
|
9231
|
+
if (signal2.aborted)
|
|
9232
9232
|
this.controller.abort();
|
|
9233
|
-
|
|
9233
|
+
signal2.addEventListener("abort", () => this.controller.abort());
|
|
9234
9234
|
}
|
|
9235
9235
|
__classPrivateFieldGet9(this, _MessageStream_instances, "m", _MessageStream_beginRequest).call(this);
|
|
9236
9236
|
this._connected(null);
|
|
@@ -9707,220 +9707,754 @@ module.exports = __toCommonJS(exports_src);
|
|
|
9707
9707
|
|
|
9708
9708
|
// src/core/engine.ts
|
|
9709
9709
|
var import_os2 = require("os");
|
|
9710
|
-
var
|
|
9710
|
+
var import_path2 = require("path");
|
|
9711
9711
|
|
|
9712
|
-
// node_modules/
|
|
9712
|
+
// node_modules/@rlabs-inc/fsdb/dist/index.mjs
|
|
9713
9713
|
var import_fs = require("fs");
|
|
9714
|
-
var
|
|
9714
|
+
var equals = (oldValue, newValue) => Object.is(oldValue, newValue);
|
|
9715
|
+
var DERIVED = 1 << 1;
|
|
9716
|
+
var EFFECT = 1 << 2;
|
|
9717
|
+
var RENDER_EFFECT = 1 << 3;
|
|
9718
|
+
var ROOT_EFFECT = 1 << 4;
|
|
9719
|
+
var BRANCH_EFFECT = 1 << 5;
|
|
9720
|
+
var USER_EFFECT = 1 << 6;
|
|
9721
|
+
var BLOCK_EFFECT = 1 << 7;
|
|
9722
|
+
var CLEAN = 1 << 10;
|
|
9723
|
+
var DIRTY = 1 << 11;
|
|
9724
|
+
var MAYBE_DIRTY = 1 << 12;
|
|
9725
|
+
var REACTION_IS_UPDATING = 1 << 13;
|
|
9726
|
+
var DESTROYED = 1 << 14;
|
|
9727
|
+
var INERT = 1 << 15;
|
|
9728
|
+
var EFFECT_RAN = 1 << 16;
|
|
9729
|
+
var EFFECT_PRESERVED = 1 << 17;
|
|
9730
|
+
var UNOWNED = 1 << 8;
|
|
9731
|
+
var DISCONNECTED = 1 << 9;
|
|
9732
|
+
var INSPECT_EFFECT = 1 << 18;
|
|
9733
|
+
var UNINITIALIZED = Symbol.for("rlabs.signals.uninitialized");
|
|
9734
|
+
var STALE_REACTION = Symbol.for("rlabs.signals.stale_reaction");
|
|
9735
|
+
var STATE_SYMBOL = Symbol.for("rlabs.signals.state");
|
|
9736
|
+
var REACTIVE_MARKER = Symbol.for("rlabs.signals.reactive");
|
|
9737
|
+
var STATUS_MASK = ~(DIRTY | MAYBE_DIRTY | CLEAN);
|
|
9715
9738
|
var activeReaction = null;
|
|
9739
|
+
var activeEffect = null;
|
|
9740
|
+
var untracking = false;
|
|
9741
|
+
var writeVersion = 1;
|
|
9742
|
+
var readVersion = 0;
|
|
9743
|
+
var newDeps = null;
|
|
9744
|
+
var skippedDeps = 0;
|
|
9745
|
+
var untrackedWrites = null;
|
|
9716
9746
|
var batchDepth = 0;
|
|
9717
9747
|
var pendingReactions = new Set;
|
|
9718
|
-
var
|
|
9719
|
-
var
|
|
9720
|
-
|
|
9721
|
-
|
|
9722
|
-
|
|
9723
|
-
|
|
9724
|
-
|
|
9725
|
-
|
|
9726
|
-
|
|
9727
|
-
|
|
9728
|
-
|
|
9729
|
-
|
|
9730
|
-
|
|
9731
|
-
|
|
9732
|
-
|
|
9733
|
-
|
|
9734
|
-
|
|
9748
|
+
var queuedRootEffects = [];
|
|
9749
|
+
var isFlushingSync = false;
|
|
9750
|
+
function setActiveReaction(reaction) {
|
|
9751
|
+
const prev = activeReaction;
|
|
9752
|
+
activeReaction = reaction;
|
|
9753
|
+
return prev;
|
|
9754
|
+
}
|
|
9755
|
+
function setActiveEffect(effect) {
|
|
9756
|
+
const prev = activeEffect;
|
|
9757
|
+
activeEffect = effect;
|
|
9758
|
+
return prev;
|
|
9759
|
+
}
|
|
9760
|
+
function incrementWriteVersion() {
|
|
9761
|
+
return ++writeVersion;
|
|
9762
|
+
}
|
|
9763
|
+
function incrementReadVersion() {
|
|
9764
|
+
return ++readVersion;
|
|
9765
|
+
}
|
|
9766
|
+
function setNewDeps(deps) {
|
|
9767
|
+
const prev = newDeps;
|
|
9768
|
+
newDeps = deps;
|
|
9769
|
+
return prev;
|
|
9770
|
+
}
|
|
9771
|
+
function setSkippedDeps(count) {
|
|
9772
|
+
const prev = skippedDeps;
|
|
9773
|
+
skippedDeps = count;
|
|
9774
|
+
return prev;
|
|
9775
|
+
}
|
|
9776
|
+
function setUntrackedWrites(writes) {
|
|
9777
|
+
const prev = untrackedWrites;
|
|
9778
|
+
untrackedWrites = writes;
|
|
9779
|
+
return prev;
|
|
9780
|
+
}
|
|
9781
|
+
function addUntrackedWrite(signal) {
|
|
9782
|
+
if (untrackedWrites === null) {
|
|
9783
|
+
untrackedWrites = [signal];
|
|
9784
|
+
} else {
|
|
9785
|
+
untrackedWrites.push(signal);
|
|
9786
|
+
}
|
|
9787
|
+
}
|
|
9788
|
+
function addPendingReaction(reaction) {
|
|
9789
|
+
pendingReactions.add(reaction);
|
|
9790
|
+
}
|
|
9791
|
+
function clearQueuedRootEffects() {
|
|
9792
|
+
const prev = queuedRootEffects;
|
|
9793
|
+
queuedRootEffects = [];
|
|
9794
|
+
return prev;
|
|
9795
|
+
}
|
|
9796
|
+
function addQueuedRootEffect(effect) {
|
|
9797
|
+
queuedRootEffects.push(effect);
|
|
9798
|
+
}
|
|
9799
|
+
function scheduleEffect(reaction) {
|
|
9800
|
+
addPendingReaction(reaction);
|
|
9801
|
+
if (batchDepth > 0) {
|
|
9802
|
+
return;
|
|
9803
|
+
}
|
|
9804
|
+
let effect = reaction;
|
|
9805
|
+
while (effect.parent !== null) {
|
|
9806
|
+
effect = effect.parent;
|
|
9807
|
+
const flags = effect.f;
|
|
9808
|
+
if ((flags & (ROOT_EFFECT | BRANCH_EFFECT)) !== 0) {
|
|
9809
|
+
if ((flags & CLEAN) === 0) {
|
|
9810
|
+
return;
|
|
9811
|
+
}
|
|
9812
|
+
effect.f ^= CLEAN;
|
|
9735
9813
|
}
|
|
9736
|
-
}
|
|
9737
|
-
|
|
9738
|
-
|
|
9739
|
-
|
|
9814
|
+
}
|
|
9815
|
+
addQueuedRootEffect(effect);
|
|
9816
|
+
if (!isFlushingSync) {
|
|
9817
|
+
queueMicrotask(flushEffects);
|
|
9818
|
+
}
|
|
9819
|
+
}
|
|
9820
|
+
var updateEffectImpl = () => {
|
|
9821
|
+
throw new Error("updateEffect not initialized - import effect.ts first");
|
|
9822
|
+
};
|
|
9823
|
+
function setUpdateEffectImpl(impl) {
|
|
9824
|
+
updateEffectImpl = impl;
|
|
9825
|
+
}
|
|
9826
|
+
function flushEffects() {
|
|
9827
|
+
const roots = clearQueuedRootEffects();
|
|
9828
|
+
for (const root of roots) {
|
|
9829
|
+
if (isDirty(root)) {
|
|
9830
|
+
updateEffectImpl(root);
|
|
9740
9831
|
}
|
|
9741
|
-
|
|
9742
|
-
|
|
9743
|
-
|
|
9744
|
-
|
|
9745
|
-
|
|
9746
|
-
|
|
9747
|
-
|
|
9748
|
-
|
|
9832
|
+
processEffectTree(root);
|
|
9833
|
+
}
|
|
9834
|
+
}
|
|
9835
|
+
function processEffectTree(effect) {
|
|
9836
|
+
let child = effect.first;
|
|
9837
|
+
while (child !== null) {
|
|
9838
|
+
const next = child.next;
|
|
9839
|
+
if (isDirty(child)) {
|
|
9840
|
+
updateEffectImpl(child);
|
|
9749
9841
|
}
|
|
9750
|
-
|
|
9751
|
-
|
|
9752
|
-
|
|
9753
|
-
|
|
9754
|
-
|
|
9755
|
-
|
|
9756
|
-
|
|
9757
|
-
|
|
9758
|
-
|
|
9759
|
-
|
|
9760
|
-
|
|
9761
|
-
|
|
9842
|
+
if (child.first !== null) {
|
|
9843
|
+
processEffectTree(child);
|
|
9844
|
+
}
|
|
9845
|
+
child = next;
|
|
9846
|
+
}
|
|
9847
|
+
}
|
|
9848
|
+
function get(signal) {
|
|
9849
|
+
if (activeReaction !== null && !untracking) {
|
|
9850
|
+
if ((activeReaction.f & REACTION_IS_UPDATING) !== 0) {
|
|
9851
|
+
if (signal.rv < readVersion) {
|
|
9852
|
+
signal.rv = readVersion;
|
|
9853
|
+
const deps = activeReaction.deps;
|
|
9854
|
+
if (newDeps === null && deps !== null && deps[skippedDeps] === signal) {
|
|
9855
|
+
setSkippedDeps(skippedDeps + 1);
|
|
9856
|
+
} else {
|
|
9857
|
+
if (newDeps === null) {
|
|
9858
|
+
setNewDeps([signal]);
|
|
9859
|
+
} else {
|
|
9860
|
+
newDeps.push(signal);
|
|
9861
|
+
}
|
|
9862
|
+
}
|
|
9863
|
+
}
|
|
9864
|
+
} else {
|
|
9865
|
+
if (activeReaction.deps === null) {
|
|
9866
|
+
activeReaction.deps = [signal];
|
|
9867
|
+
} else if (!activeReaction.deps.includes(signal)) {
|
|
9868
|
+
activeReaction.deps.push(signal);
|
|
9869
|
+
}
|
|
9870
|
+
if (signal.reactions === null) {
|
|
9871
|
+
signal.reactions = [activeReaction];
|
|
9872
|
+
} else if (!signal.reactions.includes(activeReaction)) {
|
|
9873
|
+
signal.reactions.push(activeReaction);
|
|
9762
9874
|
}
|
|
9763
|
-
return internal.v;
|
|
9764
9875
|
}
|
|
9765
|
-
}
|
|
9876
|
+
}
|
|
9877
|
+
if ((signal.f & DERIVED) !== 0) {
|
|
9878
|
+
const derived = signal;
|
|
9879
|
+
if (isDirty(derived)) {
|
|
9880
|
+
updateDerived(derived);
|
|
9881
|
+
}
|
|
9882
|
+
}
|
|
9883
|
+
return signal.v;
|
|
9766
9884
|
}
|
|
9767
|
-
|
|
9768
|
-
|
|
9769
|
-
|
|
9770
|
-
|
|
9771
|
-
|
|
9885
|
+
function set(signal, value) {
|
|
9886
|
+
if (activeReaction !== null && (activeReaction.f & DERIVED) !== 0) {
|
|
9887
|
+
throw new Error("Cannot write to signals inside a derived. " + "Deriveds should be pure computations with no side effects.");
|
|
9888
|
+
}
|
|
9889
|
+
if (!signal.equals(signal.v, value)) {
|
|
9890
|
+
signal.v = value;
|
|
9891
|
+
signal.wv = incrementWriteVersion();
|
|
9892
|
+
markReactions(signal, DIRTY);
|
|
9893
|
+
if (activeEffect !== null && (activeEffect.f & CLEAN) !== 0 && (activeEffect.f & (ROOT_EFFECT | BRANCH_EFFECT)) === 0) {
|
|
9894
|
+
addUntrackedWrite(signal);
|
|
9895
|
+
}
|
|
9772
9896
|
}
|
|
9897
|
+
return value;
|
|
9773
9898
|
}
|
|
9774
|
-
function
|
|
9775
|
-
const reactions =
|
|
9776
|
-
|
|
9777
|
-
|
|
9778
|
-
|
|
9779
|
-
|
|
9780
|
-
|
|
9899
|
+
function markReactions(signal, status) {
|
|
9900
|
+
const reactions = signal.reactions;
|
|
9901
|
+
if (reactions === null)
|
|
9902
|
+
return;
|
|
9903
|
+
for (let i = 0;i < reactions.length; i++) {
|
|
9904
|
+
const reaction = reactions[i];
|
|
9905
|
+
const flags = reaction.f;
|
|
9906
|
+
const notDirty = (flags & DIRTY) === 0;
|
|
9907
|
+
if (notDirty) {
|
|
9908
|
+
setSignalStatus(reaction, status);
|
|
9909
|
+
}
|
|
9910
|
+
if ((flags & DERIVED) !== 0) {
|
|
9911
|
+
markReactions(reaction, MAYBE_DIRTY);
|
|
9912
|
+
} else if (notDirty) {
|
|
9913
|
+
scheduleEffect(reaction);
|
|
9914
|
+
}
|
|
9915
|
+
}
|
|
9916
|
+
}
|
|
9917
|
+
function setSignalStatus(signal, status) {
|
|
9918
|
+
signal.f = signal.f & STATUS_MASK | status;
|
|
9919
|
+
}
|
|
9920
|
+
function isDirty(reaction) {
|
|
9921
|
+
if ((reaction.f & DIRTY) !== 0) {
|
|
9922
|
+
return true;
|
|
9923
|
+
}
|
|
9924
|
+
if ((reaction.f & MAYBE_DIRTY) !== 0) {
|
|
9925
|
+
const deps = reaction.deps;
|
|
9926
|
+
if (deps !== null) {
|
|
9927
|
+
for (let i = 0;i < deps.length; i++) {
|
|
9928
|
+
const dep = deps[i];
|
|
9929
|
+
if ((dep.f & DERIVED) !== 0) {
|
|
9930
|
+
if (isDirty(dep)) {
|
|
9931
|
+
updateDerived(dep);
|
|
9932
|
+
}
|
|
9933
|
+
}
|
|
9934
|
+
if (dep.wv > reaction.wv) {
|
|
9935
|
+
return true;
|
|
9936
|
+
}
|
|
9937
|
+
}
|
|
9781
9938
|
}
|
|
9782
|
-
|
|
9783
|
-
|
|
9939
|
+
setSignalStatus(reaction, CLEAN);
|
|
9940
|
+
}
|
|
9941
|
+
return false;
|
|
9942
|
+
}
|
|
9943
|
+
var updateDerivedImpl = () => {
|
|
9944
|
+
throw new Error("updateDerived not initialized - import derived.ts first");
|
|
9945
|
+
};
|
|
9946
|
+
function updateDerived(derived) {
|
|
9947
|
+
updateDerivedImpl(derived);
|
|
9948
|
+
}
|
|
9949
|
+
function setUpdateDerivedImpl(impl) {
|
|
9950
|
+
updateDerivedImpl = impl;
|
|
9951
|
+
}
|
|
9952
|
+
function removeReactions(reaction, start) {
|
|
9953
|
+
const deps = reaction.deps;
|
|
9954
|
+
if (deps === null)
|
|
9955
|
+
return;
|
|
9956
|
+
for (let i = start;i < deps.length; i++) {
|
|
9957
|
+
removeReaction(reaction, deps[i]);
|
|
9958
|
+
}
|
|
9959
|
+
}
|
|
9960
|
+
function removeReaction(reaction, dep) {
|
|
9961
|
+
const reactions = dep.reactions;
|
|
9962
|
+
if (reactions === null)
|
|
9963
|
+
return;
|
|
9964
|
+
const index = reactions.indexOf(reaction);
|
|
9965
|
+
if (index !== -1) {
|
|
9966
|
+
const last = reactions.length - 1;
|
|
9967
|
+
if (index !== last) {
|
|
9968
|
+
reactions[index] = reactions[last];
|
|
9969
|
+
}
|
|
9970
|
+
reactions.pop();
|
|
9971
|
+
if (reactions.length === 0) {
|
|
9972
|
+
dep.reactions = null;
|
|
9973
|
+
}
|
|
9974
|
+
}
|
|
9975
|
+
}
|
|
9976
|
+
function updateReaction(reaction) {
|
|
9977
|
+
const prevNewDeps = newDeps;
|
|
9978
|
+
const prevSkippedDeps = skippedDeps;
|
|
9979
|
+
const prevReaction = activeReaction;
|
|
9980
|
+
const prevUntrackedWrites = untrackedWrites;
|
|
9981
|
+
setNewDeps(null);
|
|
9982
|
+
setSkippedDeps(0);
|
|
9983
|
+
setActiveReaction(reaction);
|
|
9984
|
+
setUntrackedWrites(null);
|
|
9985
|
+
const prevReadVersion = readVersion;
|
|
9986
|
+
incrementReadVersion();
|
|
9987
|
+
reaction.f |= REACTION_IS_UPDATING;
|
|
9988
|
+
try {
|
|
9989
|
+
const result = reaction.fn();
|
|
9990
|
+
const deps = reaction.deps;
|
|
9991
|
+
if (newDeps !== null) {
|
|
9992
|
+
removeReactions(reaction, skippedDeps);
|
|
9993
|
+
if (deps !== null && skippedDeps > 0) {
|
|
9994
|
+
deps.length = skippedDeps + newDeps.length;
|
|
9995
|
+
for (let i = 0;i < newDeps.length; i++) {
|
|
9996
|
+
deps[skippedDeps + i] = newDeps[i];
|
|
9997
|
+
}
|
|
9998
|
+
} else {
|
|
9999
|
+
reaction.deps = newDeps;
|
|
10000
|
+
}
|
|
10001
|
+
const finalDeps = reaction.deps;
|
|
10002
|
+
for (let i = skippedDeps;i < finalDeps.length; i++) {
|
|
10003
|
+
const dep = finalDeps[i];
|
|
10004
|
+
if (dep.reactions === null) {
|
|
10005
|
+
dep.reactions = [reaction];
|
|
10006
|
+
} else {
|
|
10007
|
+
dep.reactions.push(reaction);
|
|
10008
|
+
}
|
|
10009
|
+
}
|
|
10010
|
+
} else if (deps !== null && skippedDeps < deps.length) {
|
|
10011
|
+
removeReactions(reaction, skippedDeps);
|
|
10012
|
+
deps.length = skippedDeps;
|
|
10013
|
+
}
|
|
10014
|
+
if (untrackedWrites !== null && reaction.deps !== null && (reaction.f & EFFECT) !== 0 && (reaction.f & DERIVED) === 0) {
|
|
10015
|
+
for (const signal of untrackedWrites) {
|
|
10016
|
+
if (reaction.deps.includes(signal)) {
|
|
10017
|
+
setSignalStatus(reaction, DIRTY);
|
|
10018
|
+
scheduleEffect(reaction);
|
|
10019
|
+
break;
|
|
10020
|
+
}
|
|
10021
|
+
}
|
|
10022
|
+
}
|
|
10023
|
+
return result;
|
|
10024
|
+
} finally {
|
|
10025
|
+
reaction.f &= ~REACTION_IS_UPDATING;
|
|
10026
|
+
setNewDeps(prevNewDeps);
|
|
10027
|
+
setSkippedDeps(prevSkippedDeps);
|
|
10028
|
+
setActiveReaction(prevReaction);
|
|
10029
|
+
if (untrackedWrites !== null) {
|
|
10030
|
+
if (prevUntrackedWrites === null) {
|
|
10031
|
+
setUntrackedWrites(untrackedWrites);
|
|
10032
|
+
} else {
|
|
10033
|
+
prevUntrackedWrites.push(...untrackedWrites);
|
|
10034
|
+
setUntrackedWrites(prevUntrackedWrites);
|
|
10035
|
+
}
|
|
9784
10036
|
} else {
|
|
9785
|
-
|
|
10037
|
+
setUntrackedWrites(prevUntrackedWrites);
|
|
9786
10038
|
}
|
|
9787
10039
|
}
|
|
9788
10040
|
}
|
|
9789
|
-
|
|
9790
|
-
|
|
9791
|
-
|
|
10041
|
+
function source(initialValue, options) {
|
|
10042
|
+
return {
|
|
10043
|
+
f: 0,
|
|
10044
|
+
v: initialValue,
|
|
10045
|
+
equals: options?.equals ?? equals,
|
|
10046
|
+
reactions: null,
|
|
10047
|
+
rv: 0,
|
|
10048
|
+
wv: 0
|
|
10049
|
+
};
|
|
10050
|
+
}
|
|
10051
|
+
function signal(initialValue, options) {
|
|
10052
|
+
const src = source(initialValue, options);
|
|
10053
|
+
return {
|
|
10054
|
+
get value() {
|
|
10055
|
+
return get(src);
|
|
10056
|
+
},
|
|
10057
|
+
set value(newValue) {
|
|
10058
|
+
set(src, newValue);
|
|
10059
|
+
}
|
|
10060
|
+
};
|
|
10061
|
+
}
|
|
10062
|
+
var proxyFn = null;
|
|
10063
|
+
function setProxyFn(fn) {
|
|
10064
|
+
proxyFn = fn;
|
|
9792
10065
|
}
|
|
9793
10066
|
function shouldProxy(value) {
|
|
9794
|
-
if (value === null || typeof value !== "object")
|
|
9795
|
-
return false;
|
|
9796
|
-
if (value[REACTIVE_MARKER])
|
|
10067
|
+
if (value === null || typeof value !== "object") {
|
|
9797
10068
|
return false;
|
|
10069
|
+
}
|
|
9798
10070
|
const proto = Object.getPrototypeOf(value);
|
|
9799
10071
|
return proto === Object.prototype || proto === Array.prototype || proto === null;
|
|
9800
10072
|
}
|
|
9801
|
-
function
|
|
9802
|
-
|
|
9803
|
-
|
|
9804
|
-
|
|
9805
|
-
const
|
|
9806
|
-
|
|
9807
|
-
|
|
9808
|
-
|
|
10073
|
+
function isProxy(value) {
|
|
10074
|
+
return value !== null && typeof value === "object" && STATE_SYMBOL in value;
|
|
10075
|
+
}
|
|
10076
|
+
function isWritable(target, prop) {
|
|
10077
|
+
const descriptor = Object.getOwnPropertyDescriptor(target, prop);
|
|
10078
|
+
return descriptor === undefined || descriptor.writable === true;
|
|
10079
|
+
}
|
|
10080
|
+
function proxy(value) {
|
|
10081
|
+
if (!shouldProxy(value) || isProxy(value)) {
|
|
10082
|
+
return value;
|
|
10083
|
+
}
|
|
10084
|
+
const sources = new Map;
|
|
10085
|
+
const version = source(0);
|
|
10086
|
+
const isArray = Array.isArray(value);
|
|
10087
|
+
if (isArray) {
|
|
10088
|
+
sources.set("length", source(value.length));
|
|
10089
|
+
}
|
|
10090
|
+
const parentReadVersion = readVersion;
|
|
10091
|
+
const withParent = (fn) => {
|
|
10092
|
+
if (readVersion === parentReadVersion) {
|
|
10093
|
+
return fn();
|
|
10094
|
+
}
|
|
10095
|
+
const prevReaction = activeReaction;
|
|
10096
|
+
setActiveReaction(null);
|
|
10097
|
+
try {
|
|
10098
|
+
return fn();
|
|
10099
|
+
} finally {
|
|
10100
|
+
setActiveReaction(prevReaction);
|
|
10101
|
+
}
|
|
9809
10102
|
};
|
|
9810
|
-
const
|
|
9811
|
-
|
|
9812
|
-
|
|
9813
|
-
|
|
9814
|
-
|
|
9815
|
-
|
|
9816
|
-
|
|
9817
|
-
|
|
9818
|
-
};
|
|
9819
|
-
propSignals.set(prop, sig);
|
|
10103
|
+
const getSource = (prop, initialValue) => {
|
|
10104
|
+
let s = sources.get(prop);
|
|
10105
|
+
if (s === undefined) {
|
|
10106
|
+
s = withParent(() => {
|
|
10107
|
+
const proxied = shouldProxy(initialValue) ? proxy(initialValue) : initialValue;
|
|
10108
|
+
return source(proxied);
|
|
10109
|
+
});
|
|
10110
|
+
sources.set(prop, s);
|
|
9820
10111
|
}
|
|
9821
|
-
return
|
|
10112
|
+
return s;
|
|
9822
10113
|
};
|
|
9823
|
-
const
|
|
9824
|
-
get(
|
|
9825
|
-
if (prop ===
|
|
9826
|
-
return
|
|
9827
|
-
const value = Reflect.get(target2, prop, receiver);
|
|
9828
|
-
if (Array.isArray(target2) && typeof value === "function") {
|
|
9829
|
-
track(internal);
|
|
9830
|
-
return value.bind(proxy);
|
|
9831
|
-
}
|
|
9832
|
-
const sig = getPropSignal(prop);
|
|
9833
|
-
track(sig);
|
|
9834
|
-
if (shouldProxy(value)) {
|
|
9835
|
-
const existingProxy = rawToProxy.get(value);
|
|
9836
|
-
if (existingProxy)
|
|
9837
|
-
return existingProxy;
|
|
9838
|
-
return createDeepReactive(value);
|
|
10114
|
+
const proxyObj = new Proxy(value, {
|
|
10115
|
+
get(target, prop, receiver) {
|
|
10116
|
+
if (prop === STATE_SYMBOL) {
|
|
10117
|
+
return value;
|
|
9839
10118
|
}
|
|
9840
|
-
|
|
10119
|
+
const exists = prop in target;
|
|
10120
|
+
const currentValue = Reflect.get(target, prop, receiver);
|
|
10121
|
+
if (isArray && typeof currentValue === "function") {
|
|
10122
|
+
get(version);
|
|
10123
|
+
return currentValue.bind(proxyObj);
|
|
10124
|
+
}
|
|
10125
|
+
if (exists || isWritable(target, prop)) {
|
|
10126
|
+
const s = getSource(prop, currentValue);
|
|
10127
|
+
const val = get(s);
|
|
10128
|
+
if (val === UNINITIALIZED) {
|
|
10129
|
+
return;
|
|
10130
|
+
}
|
|
10131
|
+
return val;
|
|
10132
|
+
}
|
|
10133
|
+
return currentValue;
|
|
9841
10134
|
},
|
|
9842
|
-
set(
|
|
9843
|
-
const
|
|
9844
|
-
|
|
9845
|
-
if (
|
|
9846
|
-
|
|
9847
|
-
|
|
9848
|
-
|
|
9849
|
-
|
|
9850
|
-
|
|
9851
|
-
|
|
9852
|
-
|
|
9853
|
-
|
|
9854
|
-
|
|
10135
|
+
set(target, prop, newValue, receiver) {
|
|
10136
|
+
const exists = prop in target;
|
|
10137
|
+
let s = sources.get(prop);
|
|
10138
|
+
if (s === undefined) {
|
|
10139
|
+
if (!exists && !isWritable(target, prop)) {
|
|
10140
|
+
return false;
|
|
10141
|
+
}
|
|
10142
|
+
s = withParent(() => source(undefined));
|
|
10143
|
+
sources.set(prop, s);
|
|
10144
|
+
}
|
|
10145
|
+
const proxied = withParent(() => shouldProxy(newValue) ? proxy(newValue) : newValue);
|
|
10146
|
+
set(s, proxied);
|
|
10147
|
+
Reflect.set(target, prop, newValue, receiver);
|
|
10148
|
+
if (isArray && prop === "length") {
|
|
10149
|
+
const oldLength = s.v;
|
|
10150
|
+
const newLength = newValue;
|
|
10151
|
+
for (let i = newLength;i < oldLength; i++) {
|
|
10152
|
+
const indexKey = String(i);
|
|
10153
|
+
const indexSource = sources.get(indexKey);
|
|
10154
|
+
if (indexSource !== undefined) {
|
|
10155
|
+
set(indexSource, UNINITIALIZED);
|
|
10156
|
+
} else if (i in target) {
|
|
10157
|
+
const deletedSource = withParent(() => source(UNINITIALIZED));
|
|
10158
|
+
sources.set(indexKey, deletedSource);
|
|
10159
|
+
}
|
|
9855
10160
|
}
|
|
9856
10161
|
}
|
|
9857
|
-
|
|
10162
|
+
if (isArray && typeof prop === "string") {
|
|
10163
|
+
const index = Number(prop);
|
|
10164
|
+
if (Number.isInteger(index) && index >= 0) {
|
|
10165
|
+
const lengthSource = sources.get("length");
|
|
10166
|
+
if (lengthSource !== undefined && index >= lengthSource.v) {
|
|
10167
|
+
set(lengthSource, index + 1);
|
|
10168
|
+
}
|
|
10169
|
+
}
|
|
10170
|
+
}
|
|
10171
|
+
if (!exists) {
|
|
10172
|
+
set(version, get(version) + 1);
|
|
10173
|
+
}
|
|
10174
|
+
return true;
|
|
9858
10175
|
},
|
|
9859
|
-
deleteProperty(
|
|
9860
|
-
const
|
|
9861
|
-
|
|
9862
|
-
|
|
9863
|
-
|
|
9864
|
-
|
|
9865
|
-
|
|
9866
|
-
|
|
10176
|
+
deleteProperty(target, prop) {
|
|
10177
|
+
const exists = prop in target;
|
|
10178
|
+
if (exists) {
|
|
10179
|
+
let s = sources.get(prop);
|
|
10180
|
+
if (s === undefined) {
|
|
10181
|
+
s = withParent(() => source(UNINITIALIZED));
|
|
10182
|
+
sources.set(prop, s);
|
|
10183
|
+
} else {
|
|
10184
|
+
set(s, UNINITIALIZED);
|
|
9867
10185
|
}
|
|
9868
|
-
|
|
10186
|
+
set(version, get(version) + 1);
|
|
9869
10187
|
}
|
|
9870
|
-
return
|
|
10188
|
+
return Reflect.deleteProperty(target, prop);
|
|
9871
10189
|
},
|
|
9872
|
-
has(
|
|
9873
|
-
if (prop ===
|
|
10190
|
+
has(target, prop) {
|
|
10191
|
+
if (prop === STATE_SYMBOL) {
|
|
9874
10192
|
return true;
|
|
9875
|
-
|
|
9876
|
-
|
|
10193
|
+
}
|
|
10194
|
+
get(version);
|
|
10195
|
+
const s = sources.get(prop);
|
|
10196
|
+
if (s !== undefined) {
|
|
10197
|
+
const val = get(s);
|
|
10198
|
+
if (val === UNINITIALIZED) {
|
|
10199
|
+
return false;
|
|
10200
|
+
}
|
|
10201
|
+
}
|
|
10202
|
+
return Reflect.has(target, prop);
|
|
10203
|
+
},
|
|
10204
|
+
ownKeys(target) {
|
|
10205
|
+
get(version);
|
|
10206
|
+
const keys = Reflect.ownKeys(target).filter((key) => {
|
|
10207
|
+
const s = sources.get(key);
|
|
10208
|
+
return s === undefined || s.v !== UNINITIALIZED;
|
|
10209
|
+
});
|
|
10210
|
+
for (const [key, s] of sources) {
|
|
10211
|
+
const k = key;
|
|
10212
|
+
if (s.v !== UNINITIALIZED && !(key in target) && !keys.includes(k)) {
|
|
10213
|
+
keys.push(k);
|
|
10214
|
+
}
|
|
10215
|
+
}
|
|
10216
|
+
return keys;
|
|
9877
10217
|
},
|
|
9878
|
-
|
|
9879
|
-
|
|
9880
|
-
|
|
10218
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
10219
|
+
const s = sources.get(prop);
|
|
10220
|
+
if (s !== undefined && s.v === UNINITIALIZED) {
|
|
10221
|
+
return;
|
|
10222
|
+
}
|
|
10223
|
+
return Reflect.getOwnPropertyDescriptor(target, prop);
|
|
9881
10224
|
}
|
|
9882
10225
|
});
|
|
9883
|
-
|
|
9884
|
-
|
|
9885
|
-
|
|
9886
|
-
|
|
10226
|
+
return proxyObj;
|
|
10227
|
+
}
|
|
10228
|
+
function createDerived(fn, options) {
|
|
10229
|
+
let flags = DERIVED | DIRTY;
|
|
10230
|
+
const parentDerived = activeReaction !== null && (activeReaction.f & DERIVED) !== 0 ? activeReaction : null;
|
|
10231
|
+
if (activeEffect === null || parentDerived !== null && (parentDerived.f & UNOWNED) !== 0) {
|
|
10232
|
+
flags |= UNOWNED;
|
|
10233
|
+
}
|
|
10234
|
+
const derived = {
|
|
10235
|
+
f: flags,
|
|
10236
|
+
fn,
|
|
10237
|
+
v: UNINITIALIZED,
|
|
10238
|
+
equals: options?.equals ?? equals,
|
|
10239
|
+
reactions: null,
|
|
10240
|
+
deps: null,
|
|
10241
|
+
effects: null,
|
|
10242
|
+
parent: parentDerived ?? activeEffect,
|
|
10243
|
+
rv: 0,
|
|
10244
|
+
wv: 0
|
|
10245
|
+
};
|
|
10246
|
+
return derived;
|
|
10247
|
+
}
|
|
10248
|
+
function executeDerived(derived) {
|
|
10249
|
+
destroyDerivedEffects(derived);
|
|
10250
|
+
const value = updateReaction(derived);
|
|
10251
|
+
return value;
|
|
10252
|
+
}
|
|
10253
|
+
function updateDerived2(derived) {
|
|
10254
|
+
const value = executeDerived(derived);
|
|
10255
|
+
if (!derived.equals(derived.v, value)) {
|
|
10256
|
+
derived.v = value;
|
|
10257
|
+
derived.wv = incrementWriteVersion();
|
|
10258
|
+
}
|
|
10259
|
+
const status = (derived.f & UNOWNED) !== 0 && derived.deps !== null ? MAYBE_DIRTY : CLEAN;
|
|
10260
|
+
setSignalStatus(derived, status);
|
|
10261
|
+
}
|
|
10262
|
+
setUpdateDerivedImpl(updateDerived2);
|
|
10263
|
+
var destroyEffectImpl = () => {};
|
|
10264
|
+
function setDestroyEffectImpl(impl) {
|
|
10265
|
+
destroyEffectImpl = impl;
|
|
10266
|
+
}
|
|
10267
|
+
function destroyDerivedEffects(derived) {
|
|
10268
|
+
const effects = derived.effects;
|
|
10269
|
+
if (effects !== null) {
|
|
10270
|
+
derived.effects = null;
|
|
10271
|
+
for (let i = 0;i < effects.length; i++) {
|
|
10272
|
+
destroyEffectImpl(effects[i]);
|
|
10273
|
+
}
|
|
10274
|
+
}
|
|
10275
|
+
}
|
|
10276
|
+
function derived(fn, options) {
|
|
10277
|
+
const d = createDerived(fn, options);
|
|
10278
|
+
return {
|
|
10279
|
+
get value() {
|
|
10280
|
+
return get(d);
|
|
10281
|
+
}
|
|
10282
|
+
};
|
|
9887
10283
|
}
|
|
9888
|
-
|
|
9889
|
-
|
|
10284
|
+
derived.by = derived;
|
|
10285
|
+
function createEffect(type, fn, sync, push = true) {
|
|
10286
|
+
const parent = activeEffect;
|
|
10287
|
+
const effect = {
|
|
10288
|
+
f: type | DIRTY,
|
|
10289
|
+
fn,
|
|
10290
|
+
deps: null,
|
|
10291
|
+
teardown: null,
|
|
10292
|
+
parent,
|
|
10293
|
+
first: null,
|
|
10294
|
+
last: null,
|
|
10295
|
+
prev: null,
|
|
10296
|
+
next: null,
|
|
10297
|
+
wv: 0
|
|
10298
|
+
};
|
|
10299
|
+
if (sync) {
|
|
10300
|
+
updateEffect(effect);
|
|
10301
|
+
effect.f |= EFFECT_RAN;
|
|
10302
|
+
} else if (fn !== null) {
|
|
10303
|
+
scheduleEffect(effect);
|
|
10304
|
+
}
|
|
10305
|
+
if (push && parent !== null) {
|
|
10306
|
+
pushEffect(effect, parent);
|
|
10307
|
+
}
|
|
10308
|
+
return effect;
|
|
10309
|
+
}
|
|
10310
|
+
function pushEffect(effect, parent) {
|
|
10311
|
+
const parentLast = parent.last;
|
|
10312
|
+
if (parentLast === null) {
|
|
10313
|
+
parent.first = parent.last = effect;
|
|
10314
|
+
} else {
|
|
10315
|
+
parentLast.next = effect;
|
|
10316
|
+
effect.prev = parentLast;
|
|
10317
|
+
parent.last = effect;
|
|
10318
|
+
}
|
|
10319
|
+
}
|
|
10320
|
+
function updateEffect(effect) {
|
|
10321
|
+
if ((effect.f & DESTROYED) !== 0)
|
|
10322
|
+
return;
|
|
10323
|
+
setSignalStatus(effect, CLEAN);
|
|
10324
|
+
const prevEffect = activeEffect;
|
|
10325
|
+
setActiveEffect(effect);
|
|
10326
|
+
try {
|
|
10327
|
+
destroyEffectChildren(effect);
|
|
10328
|
+
executeTeardown(effect);
|
|
10329
|
+
const teardown = updateReaction(effect);
|
|
10330
|
+
effect.teardown = typeof teardown === "function" ? teardown : null;
|
|
10331
|
+
effect.wv = incrementWriteVersion();
|
|
10332
|
+
} finally {
|
|
10333
|
+
setActiveEffect(prevEffect);
|
|
10334
|
+
}
|
|
10335
|
+
}
|
|
10336
|
+
setUpdateEffectImpl(updateEffect);
|
|
10337
|
+
function destroyEffect(effect, removeFromParent = true) {
|
|
10338
|
+
destroyEffectChildren(effect);
|
|
10339
|
+
removeReactions(effect, 0);
|
|
10340
|
+
setSignalStatus(effect, DESTROYED);
|
|
10341
|
+
executeTeardown(effect);
|
|
10342
|
+
if (removeFromParent && effect.parent !== null) {
|
|
10343
|
+
unlinkEffect(effect);
|
|
10344
|
+
}
|
|
10345
|
+
effect.fn = null;
|
|
10346
|
+
effect.teardown = null;
|
|
10347
|
+
effect.deps = null;
|
|
10348
|
+
effect.first = null;
|
|
10349
|
+
effect.last = null;
|
|
10350
|
+
effect.prev = null;
|
|
10351
|
+
effect.next = null;
|
|
10352
|
+
}
|
|
10353
|
+
setDestroyEffectImpl(destroyEffect);
|
|
10354
|
+
function destroyEffectChildren(effect) {
|
|
10355
|
+
let child = effect.first;
|
|
10356
|
+
effect.first = null;
|
|
10357
|
+
effect.last = null;
|
|
10358
|
+
while (child !== null) {
|
|
10359
|
+
const next = child.next;
|
|
10360
|
+
if ((child.f & (EFFECT_PRESERVED | ROOT_EFFECT)) === 0) {
|
|
10361
|
+
destroyEffect(child, false);
|
|
10362
|
+
}
|
|
10363
|
+
child = next;
|
|
10364
|
+
}
|
|
10365
|
+
}
|
|
10366
|
+
function executeTeardown(effect) {
|
|
10367
|
+
const teardown = effect.teardown;
|
|
10368
|
+
if (teardown !== null) {
|
|
10369
|
+
effect.teardown = null;
|
|
10370
|
+
teardown();
|
|
10371
|
+
}
|
|
10372
|
+
}
|
|
10373
|
+
function unlinkEffect(effect) {
|
|
10374
|
+
const { parent, prev, next } = effect;
|
|
10375
|
+
if (prev !== null) {
|
|
10376
|
+
prev.next = next;
|
|
10377
|
+
}
|
|
10378
|
+
if (next !== null) {
|
|
10379
|
+
next.prev = prev;
|
|
10380
|
+
}
|
|
10381
|
+
if (parent !== null) {
|
|
10382
|
+
if (parent.first === effect) {
|
|
10383
|
+
parent.first = next;
|
|
10384
|
+
}
|
|
10385
|
+
if (parent.last === effect) {
|
|
10386
|
+
parent.last = prev;
|
|
10387
|
+
}
|
|
10388
|
+
}
|
|
10389
|
+
effect.prev = null;
|
|
10390
|
+
effect.next = null;
|
|
10391
|
+
}
|
|
10392
|
+
function effect(fn) {
|
|
10393
|
+
const eff = createEffect(EFFECT | USER_EFFECT, fn, false);
|
|
10394
|
+
return () => destroyEffect(eff);
|
|
10395
|
+
}
|
|
10396
|
+
effect.pre = function effectPre(fn) {
|
|
10397
|
+
const eff = createEffect(RENDER_EFFECT | USER_EFFECT, fn, true);
|
|
10398
|
+
return () => destroyEffect(eff);
|
|
10399
|
+
};
|
|
10400
|
+
effect.root = function effectRoot(fn) {
|
|
10401
|
+
const eff = createEffect(ROOT_EFFECT | EFFECT_PRESERVED, fn, true);
|
|
10402
|
+
return () => destroyEffect(eff);
|
|
10403
|
+
};
|
|
10404
|
+
effect.tracking = function effectTracking() {
|
|
10405
|
+
return activeEffect !== null;
|
|
10406
|
+
};
|
|
9890
10407
|
|
|
9891
10408
|
class ReactiveMap extends Map {
|
|
9892
10409
|
#keySignals = new Map;
|
|
9893
|
-
#version =
|
|
9894
|
-
#size
|
|
10410
|
+
#version = source(0);
|
|
10411
|
+
#size;
|
|
9895
10412
|
constructor(entries) {
|
|
9896
|
-
super();
|
|
9897
|
-
|
|
9898
|
-
for (const [key, value] of entries) {
|
|
9899
|
-
super.set(key, value);
|
|
9900
|
-
}
|
|
9901
|
-
this.#size.v = super.size;
|
|
9902
|
-
}
|
|
10413
|
+
super(entries);
|
|
10414
|
+
this.#size = source(super.size);
|
|
9903
10415
|
}
|
|
9904
10416
|
#getKeySignal(key) {
|
|
9905
10417
|
let sig = this.#keySignals.get(key);
|
|
9906
|
-
if (
|
|
9907
|
-
sig =
|
|
10418
|
+
if (sig === undefined) {
|
|
10419
|
+
sig = source(0);
|
|
9908
10420
|
this.#keySignals.set(key, sig);
|
|
9909
10421
|
}
|
|
9910
10422
|
return sig;
|
|
9911
10423
|
}
|
|
10424
|
+
#increment(sig) {
|
|
10425
|
+
set(sig, sig.v + 1);
|
|
10426
|
+
}
|
|
9912
10427
|
get size() {
|
|
9913
|
-
|
|
10428
|
+
get(this.#size);
|
|
9914
10429
|
return super.size;
|
|
9915
10430
|
}
|
|
9916
10431
|
has(key) {
|
|
9917
|
-
const sig = this.#
|
|
9918
|
-
|
|
10432
|
+
const sig = this.#keySignals.get(key);
|
|
10433
|
+
if (sig === undefined) {
|
|
10434
|
+
if (!super.has(key)) {
|
|
10435
|
+
get(this.#version);
|
|
10436
|
+
return false;
|
|
10437
|
+
}
|
|
10438
|
+
const newSig = this.#getKeySignal(key);
|
|
10439
|
+
get(newSig);
|
|
10440
|
+
return true;
|
|
10441
|
+
}
|
|
10442
|
+
get(sig);
|
|
9919
10443
|
return super.has(key);
|
|
9920
10444
|
}
|
|
9921
10445
|
get(key) {
|
|
9922
|
-
const sig = this.#
|
|
9923
|
-
|
|
10446
|
+
const sig = this.#keySignals.get(key);
|
|
10447
|
+
if (sig === undefined) {
|
|
10448
|
+
const val = super.get(key);
|
|
10449
|
+
if (val !== undefined) {
|
|
10450
|
+
const newSig = this.#getKeySignal(key);
|
|
10451
|
+
get(newSig);
|
|
10452
|
+
return val;
|
|
10453
|
+
}
|
|
10454
|
+
get(this.#version);
|
|
10455
|
+
return;
|
|
10456
|
+
}
|
|
10457
|
+
get(sig);
|
|
9924
10458
|
return super.get(key);
|
|
9925
10459
|
}
|
|
9926
10460
|
set(key, value) {
|
|
@@ -9929,65 +10463,60 @@ class ReactiveMap extends Map {
|
|
|
9929
10463
|
super.set(key, value);
|
|
9930
10464
|
const sig = this.#getKeySignal(key);
|
|
9931
10465
|
if (isNew) {
|
|
9932
|
-
this.#size
|
|
9933
|
-
|
|
9934
|
-
this.#
|
|
9935
|
-
trigger(this.#version);
|
|
9936
|
-
sig.v++;
|
|
9937
|
-
trigger(sig);
|
|
10466
|
+
set(this.#size, super.size);
|
|
10467
|
+
this.#increment(this.#version);
|
|
10468
|
+
this.#increment(sig);
|
|
9938
10469
|
} else if (!Object.is(oldValue, value)) {
|
|
9939
|
-
sig
|
|
9940
|
-
|
|
10470
|
+
this.#increment(sig);
|
|
10471
|
+
const versionReactions = this.#version.reactions;
|
|
10472
|
+
const keyReactions = sig.reactions;
|
|
10473
|
+
if (keyReactions !== null && (versionReactions === null || !keyReactions.every((r) => versionReactions.includes(r)))) {
|
|
10474
|
+
this.#increment(this.#version);
|
|
10475
|
+
}
|
|
9941
10476
|
}
|
|
9942
10477
|
return this;
|
|
9943
10478
|
}
|
|
9944
10479
|
delete(key) {
|
|
9945
|
-
const
|
|
9946
|
-
|
|
9947
|
-
|
|
10480
|
+
const existed = super.has(key);
|
|
10481
|
+
if (existed) {
|
|
10482
|
+
super.delete(key);
|
|
9948
10483
|
const sig = this.#keySignals.get(key);
|
|
9949
|
-
if (sig) {
|
|
9950
|
-
sig
|
|
9951
|
-
trigger(sig);
|
|
10484
|
+
if (sig !== undefined) {
|
|
10485
|
+
set(sig, -1);
|
|
9952
10486
|
this.#keySignals.delete(key);
|
|
9953
10487
|
}
|
|
9954
|
-
this.#size
|
|
9955
|
-
|
|
9956
|
-
this.#version.v++;
|
|
9957
|
-
trigger(this.#version);
|
|
10488
|
+
set(this.#size, super.size);
|
|
10489
|
+
this.#increment(this.#version);
|
|
9958
10490
|
}
|
|
9959
|
-
return
|
|
10491
|
+
return existed;
|
|
9960
10492
|
}
|
|
9961
10493
|
clear() {
|
|
9962
|
-
if (super.size
|
|
9963
|
-
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
10494
|
+
if (super.size > 0) {
|
|
10495
|
+
for (const [key, sig] of this.#keySignals) {
|
|
10496
|
+
set(sig, -1);
|
|
10497
|
+
}
|
|
10498
|
+
this.#keySignals.clear();
|
|
10499
|
+
super.clear();
|
|
10500
|
+
set(this.#size, 0);
|
|
10501
|
+
this.#increment(this.#version);
|
|
9967
10502
|
}
|
|
9968
|
-
super.clear();
|
|
9969
|
-
this.#keySignals.clear();
|
|
9970
|
-
this.#size.v = 0;
|
|
9971
|
-
trigger(this.#size);
|
|
9972
|
-
this.#version.v++;
|
|
9973
|
-
trigger(this.#version);
|
|
9974
|
-
}
|
|
9975
|
-
forEach(callbackfn, thisArg) {
|
|
9976
|
-
track(this.#version);
|
|
9977
|
-
super.forEach(callbackfn, thisArg);
|
|
9978
10503
|
}
|
|
9979
10504
|
keys() {
|
|
9980
|
-
|
|
10505
|
+
get(this.#version);
|
|
9981
10506
|
return super.keys();
|
|
9982
10507
|
}
|
|
9983
10508
|
values() {
|
|
9984
|
-
|
|
10509
|
+
get(this.#version);
|
|
9985
10510
|
return super.values();
|
|
9986
10511
|
}
|
|
9987
10512
|
entries() {
|
|
9988
|
-
|
|
10513
|
+
get(this.#version);
|
|
9989
10514
|
return super.entries();
|
|
9990
10515
|
}
|
|
10516
|
+
forEach(callbackfn, thisArg) {
|
|
10517
|
+
get(this.#version);
|
|
10518
|
+
super.forEach(callbackfn, thisArg);
|
|
10519
|
+
}
|
|
9991
10520
|
[Symbol.iterator]() {
|
|
9992
10521
|
return this.entries();
|
|
9993
10522
|
}
|
|
@@ -9995,375 +10524,857 @@ class ReactiveMap extends Map {
|
|
|
9995
10524
|
|
|
9996
10525
|
class ReactiveSet extends Set {
|
|
9997
10526
|
#itemSignals = new Map;
|
|
9998
|
-
#version =
|
|
9999
|
-
#size
|
|
10527
|
+
#version = source(0);
|
|
10528
|
+
#size;
|
|
10000
10529
|
constructor(values) {
|
|
10001
|
-
super();
|
|
10002
|
-
|
|
10003
|
-
for (const value of values) {
|
|
10004
|
-
super.add(value);
|
|
10005
|
-
}
|
|
10006
|
-
this.#size.v = super.size;
|
|
10007
|
-
}
|
|
10530
|
+
super(values);
|
|
10531
|
+
this.#size = source(super.size);
|
|
10008
10532
|
}
|
|
10009
10533
|
#getItemSignal(item) {
|
|
10010
10534
|
let sig = this.#itemSignals.get(item);
|
|
10011
|
-
if (
|
|
10012
|
-
sig =
|
|
10535
|
+
if (sig === undefined) {
|
|
10536
|
+
sig = source(super.has(item));
|
|
10013
10537
|
this.#itemSignals.set(item, sig);
|
|
10014
10538
|
}
|
|
10015
10539
|
return sig;
|
|
10016
10540
|
}
|
|
10541
|
+
#incrementVersion() {
|
|
10542
|
+
set(this.#version, this.#version.v + 1);
|
|
10543
|
+
}
|
|
10017
10544
|
get size() {
|
|
10018
|
-
|
|
10545
|
+
get(this.#size);
|
|
10019
10546
|
return super.size;
|
|
10020
10547
|
}
|
|
10021
|
-
has(
|
|
10022
|
-
const sig = this.#
|
|
10023
|
-
|
|
10024
|
-
|
|
10025
|
-
|
|
10026
|
-
|
|
10027
|
-
|
|
10028
|
-
|
|
10029
|
-
|
|
10030
|
-
|
|
10031
|
-
|
|
10032
|
-
|
|
10033
|
-
|
|
10034
|
-
|
|
10035
|
-
|
|
10548
|
+
has(item) {
|
|
10549
|
+
const sig = this.#itemSignals.get(item);
|
|
10550
|
+
if (sig === undefined) {
|
|
10551
|
+
const exists = super.has(item);
|
|
10552
|
+
if (exists) {
|
|
10553
|
+
const newSig = this.#getItemSignal(item);
|
|
10554
|
+
get(newSig);
|
|
10555
|
+
return true;
|
|
10556
|
+
}
|
|
10557
|
+
get(this.#version);
|
|
10558
|
+
return false;
|
|
10559
|
+
}
|
|
10560
|
+
get(sig);
|
|
10561
|
+
return super.has(item);
|
|
10562
|
+
}
|
|
10563
|
+
add(item) {
|
|
10564
|
+
const isNew = !super.has(item);
|
|
10565
|
+
super.add(item);
|
|
10566
|
+
if (isNew) {
|
|
10567
|
+
const sig = this.#getItemSignal(item);
|
|
10568
|
+
set(sig, true);
|
|
10569
|
+
set(this.#size, super.size);
|
|
10570
|
+
this.#incrementVersion();
|
|
10036
10571
|
}
|
|
10037
10572
|
return this;
|
|
10038
10573
|
}
|
|
10039
|
-
delete(
|
|
10040
|
-
const
|
|
10041
|
-
|
|
10042
|
-
|
|
10043
|
-
const sig = this.#itemSignals.get(
|
|
10044
|
-
if (sig) {
|
|
10045
|
-
sig
|
|
10046
|
-
|
|
10047
|
-
|
|
10048
|
-
|
|
10049
|
-
this.#
|
|
10050
|
-
trigger(this.#size);
|
|
10051
|
-
this.#version.v++;
|
|
10052
|
-
trigger(this.#version);
|
|
10574
|
+
delete(item) {
|
|
10575
|
+
const existed = super.has(item);
|
|
10576
|
+
if (existed) {
|
|
10577
|
+
super.delete(item);
|
|
10578
|
+
const sig = this.#itemSignals.get(item);
|
|
10579
|
+
if (sig !== undefined) {
|
|
10580
|
+
set(sig, false);
|
|
10581
|
+
this.#itemSignals.delete(item);
|
|
10582
|
+
}
|
|
10583
|
+
set(this.#size, super.size);
|
|
10584
|
+
this.#incrementVersion();
|
|
10053
10585
|
}
|
|
10054
|
-
return
|
|
10586
|
+
return existed;
|
|
10055
10587
|
}
|
|
10056
10588
|
clear() {
|
|
10057
|
-
if (super.size
|
|
10058
|
-
|
|
10059
|
-
|
|
10060
|
-
|
|
10061
|
-
|
|
10589
|
+
if (super.size > 0) {
|
|
10590
|
+
for (const [item, sig] of this.#itemSignals) {
|
|
10591
|
+
set(sig, false);
|
|
10592
|
+
}
|
|
10593
|
+
this.#itemSignals.clear();
|
|
10594
|
+
super.clear();
|
|
10595
|
+
set(this.#size, 0);
|
|
10596
|
+
this.#incrementVersion();
|
|
10062
10597
|
}
|
|
10063
|
-
super.clear();
|
|
10064
|
-
this.#itemSignals.clear();
|
|
10065
|
-
this.#size.v = 0;
|
|
10066
|
-
trigger(this.#size);
|
|
10067
|
-
this.#version.v++;
|
|
10068
|
-
trigger(this.#version);
|
|
10069
|
-
}
|
|
10070
|
-
forEach(callbackfn, thisArg) {
|
|
10071
|
-
track(this.#version);
|
|
10072
|
-
super.forEach(callbackfn, thisArg);
|
|
10073
10598
|
}
|
|
10074
10599
|
keys() {
|
|
10075
|
-
|
|
10600
|
+
get(this.#version);
|
|
10076
10601
|
return super.keys();
|
|
10077
10602
|
}
|
|
10078
10603
|
values() {
|
|
10079
|
-
|
|
10604
|
+
get(this.#version);
|
|
10080
10605
|
return super.values();
|
|
10081
10606
|
}
|
|
10082
10607
|
entries() {
|
|
10083
|
-
|
|
10608
|
+
get(this.#version);
|
|
10084
10609
|
return super.entries();
|
|
10085
10610
|
}
|
|
10611
|
+
forEach(callbackfn, thisArg) {
|
|
10612
|
+
get(this.#version);
|
|
10613
|
+
super.forEach(callbackfn, thisArg);
|
|
10614
|
+
}
|
|
10086
10615
|
[Symbol.iterator]() {
|
|
10087
10616
|
return this.values();
|
|
10088
10617
|
}
|
|
10089
10618
|
}
|
|
10090
|
-
|
|
10091
|
-
|
|
10092
|
-
|
|
10093
|
-
|
|
10094
|
-
|
|
10095
|
-
|
|
10096
|
-
get count() {
|
|
10097
|
-
return this.allocatedIndices.size;
|
|
10619
|
+
|
|
10620
|
+
class ReactiveDate extends Date {
|
|
10621
|
+
#time;
|
|
10622
|
+
constructor(...args) {
|
|
10623
|
+
super(...args);
|
|
10624
|
+
this.#time = source(super.getTime());
|
|
10098
10625
|
}
|
|
10099
|
-
|
|
10100
|
-
|
|
10101
|
-
|
|
10102
|
-
|
|
10103
|
-
return existing;
|
|
10104
|
-
let index;
|
|
10105
|
-
if (registry.freeIndices.length > 0) {
|
|
10106
|
-
index = registry.freeIndices.pop();
|
|
10107
|
-
} else {
|
|
10108
|
-
index = registry.nextIndex++;
|
|
10626
|
+
#update() {
|
|
10627
|
+
const time = super.getTime();
|
|
10628
|
+
set(this.#time, time);
|
|
10629
|
+
return time;
|
|
10109
10630
|
}
|
|
10110
|
-
|
|
10111
|
-
|
|
10112
|
-
|
|
10113
|
-
return index;
|
|
10114
|
-
}
|
|
10115
|
-
function releaseIndex(id) {
|
|
10116
|
-
const index = registry.idToIndex.get(id);
|
|
10117
|
-
if (index === undefined)
|
|
10118
|
-
return;
|
|
10119
|
-
registry.idToIndex.delete(id);
|
|
10120
|
-
registry.indexToId.delete(index);
|
|
10121
|
-
registry.allocatedIndices.delete(index);
|
|
10122
|
-
registry.freeIndices.push(index);
|
|
10123
|
-
return index;
|
|
10124
|
-
}
|
|
10125
|
-
function getIndex(id) {
|
|
10126
|
-
return registry.idToIndex.get(id);
|
|
10127
|
-
}
|
|
10128
|
-
function getId(index) {
|
|
10129
|
-
return registry.indexToId.get(index);
|
|
10130
|
-
}
|
|
10131
|
-
function getAllIndices() {
|
|
10132
|
-
return Array.from(registry.allocatedIndices);
|
|
10133
|
-
}
|
|
10134
|
-
function resetRegistry() {
|
|
10135
|
-
registry.idToIndex.clear();
|
|
10136
|
-
registry.indexToId.clear();
|
|
10137
|
-
registry.allocatedIndices.clear();
|
|
10138
|
-
registry.freeIndices.length = 0;
|
|
10139
|
-
registry.nextIndex = 0;
|
|
10140
|
-
}
|
|
10141
|
-
function parseColumnType(type) {
|
|
10142
|
-
if (type === "string" || type === "timestamp") {
|
|
10143
|
-
return { baseType: "string" };
|
|
10631
|
+
getTime() {
|
|
10632
|
+
get(this.#time);
|
|
10633
|
+
return super.getTime();
|
|
10144
10634
|
}
|
|
10145
|
-
|
|
10146
|
-
|
|
10635
|
+
getFullYear() {
|
|
10636
|
+
get(this.#time);
|
|
10637
|
+
return super.getFullYear();
|
|
10147
10638
|
}
|
|
10148
|
-
|
|
10149
|
-
|
|
10639
|
+
getMonth() {
|
|
10640
|
+
get(this.#time);
|
|
10641
|
+
return super.getMonth();
|
|
10150
10642
|
}
|
|
10151
|
-
|
|
10152
|
-
|
|
10643
|
+
getDate() {
|
|
10644
|
+
get(this.#time);
|
|
10645
|
+
return super.getDate();
|
|
10153
10646
|
}
|
|
10154
|
-
|
|
10155
|
-
|
|
10647
|
+
getDay() {
|
|
10648
|
+
get(this.#time);
|
|
10649
|
+
return super.getDay();
|
|
10156
10650
|
}
|
|
10157
|
-
|
|
10158
|
-
|
|
10159
|
-
return
|
|
10651
|
+
getHours() {
|
|
10652
|
+
get(this.#time);
|
|
10653
|
+
return super.getHours();
|
|
10160
10654
|
}
|
|
10161
|
-
|
|
10162
|
-
|
|
10163
|
-
|
|
10164
|
-
const columns = Object.keys(definition);
|
|
10165
|
-
const vectorColumns = columns.filter((col) => {
|
|
10166
|
-
const type = definition[col];
|
|
10167
|
-
return typeof type === "string" && type.startsWith("vector:");
|
|
10168
|
-
});
|
|
10169
|
-
return {
|
|
10170
|
-
definition,
|
|
10171
|
-
columns,
|
|
10172
|
-
vectorColumns
|
|
10173
|
-
};
|
|
10174
|
-
}
|
|
10175
|
-
function getDefaultForType(type) {
|
|
10176
|
-
const parsed = parseColumnType(type);
|
|
10177
|
-
switch (parsed.baseType) {
|
|
10178
|
-
case "string":
|
|
10179
|
-
return "";
|
|
10180
|
-
case "number":
|
|
10181
|
-
return 0;
|
|
10182
|
-
case "boolean":
|
|
10183
|
-
return false;
|
|
10184
|
-
case "array":
|
|
10185
|
-
return [];
|
|
10186
|
-
case "vector":
|
|
10187
|
-
return null;
|
|
10188
|
-
default:
|
|
10189
|
-
return null;
|
|
10655
|
+
getMinutes() {
|
|
10656
|
+
get(this.#time);
|
|
10657
|
+
return super.getMinutes();
|
|
10190
10658
|
}
|
|
10191
|
-
|
|
10192
|
-
|
|
10193
|
-
|
|
10194
|
-
_arrays = new ReactiveMap;
|
|
10195
|
-
_indexes = new ReactiveMap;
|
|
10196
|
-
_schema;
|
|
10197
|
-
constructor(schema) {
|
|
10198
|
-
this._schema = schema;
|
|
10199
|
-
for (const name of Object.keys(schema)) {
|
|
10200
|
-
this._arrays.set(name, []);
|
|
10201
|
-
}
|
|
10659
|
+
getSeconds() {
|
|
10660
|
+
get(this.#time);
|
|
10661
|
+
return super.getSeconds();
|
|
10202
10662
|
}
|
|
10203
|
-
|
|
10204
|
-
|
|
10663
|
+
getMilliseconds() {
|
|
10664
|
+
get(this.#time);
|
|
10665
|
+
return super.getMilliseconds();
|
|
10205
10666
|
}
|
|
10206
|
-
|
|
10207
|
-
|
|
10208
|
-
|
|
10209
|
-
this._updateIndex(column, index, value);
|
|
10667
|
+
getUTCFullYear() {
|
|
10668
|
+
get(this.#time);
|
|
10669
|
+
return super.getUTCFullYear();
|
|
10210
10670
|
}
|
|
10211
|
-
|
|
10212
|
-
|
|
10671
|
+
getUTCMonth() {
|
|
10672
|
+
get(this.#time);
|
|
10673
|
+
return super.getUTCMonth();
|
|
10213
10674
|
}
|
|
10214
|
-
|
|
10215
|
-
|
|
10216
|
-
|
|
10217
|
-
|
|
10218
|
-
|
|
10675
|
+
getUTCDate() {
|
|
10676
|
+
get(this.#time);
|
|
10677
|
+
return super.getUTCDate();
|
|
10678
|
+
}
|
|
10679
|
+
getUTCDay() {
|
|
10680
|
+
get(this.#time);
|
|
10681
|
+
return super.getUTCDay();
|
|
10682
|
+
}
|
|
10683
|
+
getUTCHours() {
|
|
10684
|
+
get(this.#time);
|
|
10685
|
+
return super.getUTCHours();
|
|
10686
|
+
}
|
|
10687
|
+
getUTCMinutes() {
|
|
10688
|
+
get(this.#time);
|
|
10689
|
+
return super.getUTCMinutes();
|
|
10690
|
+
}
|
|
10691
|
+
getUTCSeconds() {
|
|
10692
|
+
get(this.#time);
|
|
10693
|
+
return super.getUTCSeconds();
|
|
10694
|
+
}
|
|
10695
|
+
getUTCMilliseconds() {
|
|
10696
|
+
get(this.#time);
|
|
10697
|
+
return super.getUTCMilliseconds();
|
|
10698
|
+
}
|
|
10699
|
+
getTimezoneOffset() {
|
|
10700
|
+
get(this.#time);
|
|
10701
|
+
return super.getTimezoneOffset();
|
|
10702
|
+
}
|
|
10703
|
+
setTime(time) {
|
|
10704
|
+
super.setTime(time);
|
|
10705
|
+
return this.#update();
|
|
10706
|
+
}
|
|
10707
|
+
setFullYear(year, month, date) {
|
|
10708
|
+
if (date !== undefined) {
|
|
10709
|
+
super.setFullYear(year, month, date);
|
|
10710
|
+
} else if (month !== undefined) {
|
|
10711
|
+
super.setFullYear(year, month);
|
|
10712
|
+
} else {
|
|
10713
|
+
super.setFullYear(year);
|
|
10219
10714
|
}
|
|
10715
|
+
return this.#update();
|
|
10220
10716
|
}
|
|
10221
|
-
|
|
10222
|
-
|
|
10223
|
-
|
|
10224
|
-
|
|
10717
|
+
setMonth(month, date) {
|
|
10718
|
+
if (date !== undefined) {
|
|
10719
|
+
super.setMonth(month, date);
|
|
10720
|
+
} else {
|
|
10721
|
+
super.setMonth(month);
|
|
10225
10722
|
}
|
|
10226
|
-
return
|
|
10723
|
+
return this.#update();
|
|
10227
10724
|
}
|
|
10228
|
-
|
|
10229
|
-
|
|
10230
|
-
|
|
10231
|
-
|
|
10232
|
-
|
|
10233
|
-
|
|
10234
|
-
|
|
10235
|
-
|
|
10236
|
-
|
|
10237
|
-
|
|
10238
|
-
|
|
10239
|
-
|
|
10240
|
-
|
|
10241
|
-
break;
|
|
10242
|
-
case "array":
|
|
10243
|
-
arr[index] = [];
|
|
10244
|
-
break;
|
|
10245
|
-
case "vector":
|
|
10246
|
-
arr[index] = null;
|
|
10247
|
-
break;
|
|
10248
|
-
}
|
|
10725
|
+
setDate(date) {
|
|
10726
|
+
super.setDate(date);
|
|
10727
|
+
return this.#update();
|
|
10728
|
+
}
|
|
10729
|
+
setHours(hours, min, sec, ms) {
|
|
10730
|
+
if (ms !== undefined) {
|
|
10731
|
+
super.setHours(hours, min, sec, ms);
|
|
10732
|
+
} else if (sec !== undefined) {
|
|
10733
|
+
super.setHours(hours, min, sec);
|
|
10734
|
+
} else if (min !== undefined) {
|
|
10735
|
+
super.setHours(hours, min);
|
|
10736
|
+
} else {
|
|
10737
|
+
super.setHours(hours);
|
|
10249
10738
|
}
|
|
10739
|
+
return this.#update();
|
|
10250
10740
|
}
|
|
10251
|
-
|
|
10252
|
-
if (
|
|
10253
|
-
|
|
10741
|
+
setMinutes(min, sec, ms) {
|
|
10742
|
+
if (ms !== undefined) {
|
|
10743
|
+
super.setMinutes(min, sec, ms);
|
|
10744
|
+
} else if (sec !== undefined) {
|
|
10745
|
+
super.setMinutes(min, sec);
|
|
10746
|
+
} else {
|
|
10747
|
+
super.setMinutes(min);
|
|
10254
10748
|
}
|
|
10255
|
-
|
|
10256
|
-
|
|
10257
|
-
|
|
10258
|
-
|
|
10259
|
-
|
|
10260
|
-
|
|
10261
|
-
|
|
10262
|
-
|
|
10263
|
-
|
|
10264
|
-
|
|
10749
|
+
return this.#update();
|
|
10750
|
+
}
|
|
10751
|
+
setSeconds(sec, ms) {
|
|
10752
|
+
if (ms !== undefined) {
|
|
10753
|
+
super.setSeconds(sec, ms);
|
|
10754
|
+
} else {
|
|
10755
|
+
super.setSeconds(sec);
|
|
10756
|
+
}
|
|
10757
|
+
return this.#update();
|
|
10758
|
+
}
|
|
10759
|
+
setMilliseconds(ms) {
|
|
10760
|
+
super.setMilliseconds(ms);
|
|
10761
|
+
return this.#update();
|
|
10762
|
+
}
|
|
10763
|
+
setUTCFullYear(year, month, date) {
|
|
10764
|
+
if (date !== undefined) {
|
|
10765
|
+
super.setUTCFullYear(year, month, date);
|
|
10766
|
+
} else if (month !== undefined) {
|
|
10767
|
+
super.setUTCFullYear(year, month);
|
|
10768
|
+
} else {
|
|
10769
|
+
super.setUTCFullYear(year);
|
|
10770
|
+
}
|
|
10771
|
+
return this.#update();
|
|
10772
|
+
}
|
|
10773
|
+
setUTCMonth(month, date) {
|
|
10774
|
+
if (date !== undefined) {
|
|
10775
|
+
super.setUTCMonth(month, date);
|
|
10776
|
+
} else {
|
|
10777
|
+
super.setUTCMonth(month);
|
|
10778
|
+
}
|
|
10779
|
+
return this.#update();
|
|
10780
|
+
}
|
|
10781
|
+
setUTCDate(date) {
|
|
10782
|
+
super.setUTCDate(date);
|
|
10783
|
+
return this.#update();
|
|
10784
|
+
}
|
|
10785
|
+
setUTCHours(hours, min, sec, ms) {
|
|
10786
|
+
if (ms !== undefined) {
|
|
10787
|
+
super.setUTCHours(hours, min, sec, ms);
|
|
10788
|
+
} else if (sec !== undefined) {
|
|
10789
|
+
super.setUTCHours(hours, min, sec);
|
|
10790
|
+
} else if (min !== undefined) {
|
|
10791
|
+
super.setUTCHours(hours, min);
|
|
10792
|
+
} else {
|
|
10793
|
+
super.setUTCHours(hours);
|
|
10794
|
+
}
|
|
10795
|
+
return this.#update();
|
|
10796
|
+
}
|
|
10797
|
+
setUTCMinutes(min, sec, ms) {
|
|
10798
|
+
if (ms !== undefined) {
|
|
10799
|
+
super.setUTCMinutes(min, sec, ms);
|
|
10800
|
+
} else if (sec !== undefined) {
|
|
10801
|
+
super.setUTCMinutes(min, sec);
|
|
10802
|
+
} else {
|
|
10803
|
+
super.setUTCMinutes(min);
|
|
10804
|
+
}
|
|
10805
|
+
return this.#update();
|
|
10806
|
+
}
|
|
10807
|
+
setUTCSeconds(sec, ms) {
|
|
10808
|
+
if (ms !== undefined) {
|
|
10809
|
+
super.setUTCSeconds(sec, ms);
|
|
10810
|
+
} else {
|
|
10811
|
+
super.setUTCSeconds(sec);
|
|
10812
|
+
}
|
|
10813
|
+
return this.#update();
|
|
10814
|
+
}
|
|
10815
|
+
setUTCMilliseconds(ms) {
|
|
10816
|
+
super.setUTCMilliseconds(ms);
|
|
10817
|
+
return this.#update();
|
|
10818
|
+
}
|
|
10819
|
+
toString() {
|
|
10820
|
+
get(this.#time);
|
|
10821
|
+
return super.toString();
|
|
10822
|
+
}
|
|
10823
|
+
toDateString() {
|
|
10824
|
+
get(this.#time);
|
|
10825
|
+
return super.toDateString();
|
|
10826
|
+
}
|
|
10827
|
+
toTimeString() {
|
|
10828
|
+
get(this.#time);
|
|
10829
|
+
return super.toTimeString();
|
|
10830
|
+
}
|
|
10831
|
+
toISOString() {
|
|
10832
|
+
get(this.#time);
|
|
10833
|
+
return super.toISOString();
|
|
10834
|
+
}
|
|
10835
|
+
toUTCString() {
|
|
10836
|
+
get(this.#time);
|
|
10837
|
+
return super.toUTCString();
|
|
10838
|
+
}
|
|
10839
|
+
toLocaleString(locales, options) {
|
|
10840
|
+
get(this.#time);
|
|
10841
|
+
return super.toLocaleString(locales, options);
|
|
10842
|
+
}
|
|
10843
|
+
toLocaleDateString(locales, options) {
|
|
10844
|
+
get(this.#time);
|
|
10845
|
+
return super.toLocaleDateString(locales, options);
|
|
10846
|
+
}
|
|
10847
|
+
toLocaleTimeString(locales, options) {
|
|
10848
|
+
get(this.#time);
|
|
10849
|
+
return super.toLocaleTimeString(locales, options);
|
|
10850
|
+
}
|
|
10851
|
+
toJSON() {
|
|
10852
|
+
get(this.#time);
|
|
10853
|
+
return super.toJSON();
|
|
10854
|
+
}
|
|
10855
|
+
valueOf() {
|
|
10856
|
+
get(this.#time);
|
|
10857
|
+
return super.valueOf();
|
|
10858
|
+
}
|
|
10859
|
+
}
|
|
10860
|
+
setProxyFn(proxy);
|
|
10861
|
+
function createRegistry() {
|
|
10862
|
+
const idToIndex = new ReactiveMap;
|
|
10863
|
+
const indexToId = new ReactiveMap;
|
|
10864
|
+
const allocatedIndices = new ReactiveSet;
|
|
10865
|
+
const freeIndices = [];
|
|
10866
|
+
const _nextIndex = signal(0);
|
|
10867
|
+
const registry = {
|
|
10868
|
+
idToIndex,
|
|
10869
|
+
indexToId,
|
|
10870
|
+
allocatedIndices,
|
|
10871
|
+
freeIndices,
|
|
10872
|
+
get nextIndex() {
|
|
10873
|
+
return _nextIndex.value;
|
|
10874
|
+
},
|
|
10875
|
+
set nextIndex(value) {
|
|
10876
|
+
_nextIndex.value = value;
|
|
10877
|
+
},
|
|
10878
|
+
allocate(id) {
|
|
10879
|
+
const existingIndex = idToIndex.get(id);
|
|
10880
|
+
if (existingIndex !== undefined) {
|
|
10881
|
+
return existingIndex;
|
|
10882
|
+
}
|
|
10883
|
+
let index;
|
|
10884
|
+
if (freeIndices.length > 0) {
|
|
10885
|
+
index = freeIndices.pop();
|
|
10886
|
+
} else {
|
|
10887
|
+
index = _nextIndex.value;
|
|
10888
|
+
_nextIndex.value++;
|
|
10265
10889
|
}
|
|
10890
|
+
idToIndex.set(id, index);
|
|
10891
|
+
indexToId.set(index, id);
|
|
10892
|
+
allocatedIndices.add(index);
|
|
10893
|
+
return index;
|
|
10894
|
+
},
|
|
10895
|
+
release(id) {
|
|
10896
|
+
const index = idToIndex.get(id);
|
|
10897
|
+
if (index === undefined) {
|
|
10898
|
+
return false;
|
|
10899
|
+
}
|
|
10900
|
+
idToIndex.delete(id);
|
|
10901
|
+
indexToId.delete(index);
|
|
10902
|
+
allocatedIndices.delete(index);
|
|
10903
|
+
freeIndices.push(index);
|
|
10904
|
+
return true;
|
|
10905
|
+
},
|
|
10906
|
+
getIndex(id) {
|
|
10907
|
+
return idToIndex.get(id) ?? -1;
|
|
10908
|
+
},
|
|
10909
|
+
getId(index) {
|
|
10910
|
+
return indexToId.get(index);
|
|
10911
|
+
},
|
|
10912
|
+
has(id) {
|
|
10913
|
+
return idToIndex.has(id);
|
|
10914
|
+
},
|
|
10915
|
+
getAllIds() {
|
|
10916
|
+
return Array.from(idToIndex.keys());
|
|
10917
|
+
},
|
|
10918
|
+
getAllIndices() {
|
|
10919
|
+
return Array.from(allocatedIndices);
|
|
10920
|
+
},
|
|
10921
|
+
get count() {
|
|
10922
|
+
return idToIndex.size;
|
|
10923
|
+
},
|
|
10924
|
+
reset() {
|
|
10925
|
+
idToIndex.clear();
|
|
10926
|
+
indexToId.clear();
|
|
10927
|
+
allocatedIndices.clear();
|
|
10928
|
+
freeIndices.length = 0;
|
|
10929
|
+
_nextIndex.value = 0;
|
|
10266
10930
|
}
|
|
10267
|
-
|
|
10931
|
+
};
|
|
10932
|
+
return registry;
|
|
10933
|
+
}
|
|
10934
|
+
function generateId() {
|
|
10935
|
+
const timestamp = Date.now();
|
|
10936
|
+
const random = Math.random().toString(36).substring(2, 8);
|
|
10937
|
+
return `${timestamp}-${random}`;
|
|
10938
|
+
}
|
|
10939
|
+
var DEFAULT_VALUES = {
|
|
10940
|
+
string: "",
|
|
10941
|
+
number: 0,
|
|
10942
|
+
boolean: false,
|
|
10943
|
+
timestamp: 0,
|
|
10944
|
+
"string[]": [],
|
|
10945
|
+
"number[]": [],
|
|
10946
|
+
vector: null
|
|
10947
|
+
};
|
|
10948
|
+
var WATCHER_DEBOUNCE_MS = 100;
|
|
10949
|
+
var SAVE_GRACE_PERIOD_MS = 200;
|
|
10950
|
+
function parseColumnType(type) {
|
|
10951
|
+
if (type === "string")
|
|
10952
|
+
return { baseType: "string" };
|
|
10953
|
+
if (type === "number")
|
|
10954
|
+
return { baseType: "number" };
|
|
10955
|
+
if (type === "boolean")
|
|
10956
|
+
return { baseType: "boolean" };
|
|
10957
|
+
if (type === "timestamp")
|
|
10958
|
+
return { baseType: "timestamp" };
|
|
10959
|
+
if (type === "string[]")
|
|
10960
|
+
return { baseType: "array", arrayType: "string" };
|
|
10961
|
+
if (type === "number[]")
|
|
10962
|
+
return { baseType: "array", arrayType: "number" };
|
|
10963
|
+
const vectorMatch = type.match(/^vector:(\d+)$/);
|
|
10964
|
+
if (vectorMatch) {
|
|
10965
|
+
return {
|
|
10966
|
+
baseType: "vector",
|
|
10967
|
+
vectorDimensions: parseInt(vectorMatch[1], 10)
|
|
10968
|
+
};
|
|
10969
|
+
}
|
|
10970
|
+
throw new Error(`Unknown column type: ${type}`);
|
|
10971
|
+
}
|
|
10972
|
+
function getDefaultValue(type) {
|
|
10973
|
+
const parsed = parseColumnType(type);
|
|
10974
|
+
switch (parsed.baseType) {
|
|
10975
|
+
case "string":
|
|
10976
|
+
return DEFAULT_VALUES.string;
|
|
10977
|
+
case "number":
|
|
10978
|
+
case "timestamp":
|
|
10979
|
+
return DEFAULT_VALUES.number;
|
|
10980
|
+
case "boolean":
|
|
10981
|
+
return DEFAULT_VALUES.boolean;
|
|
10982
|
+
case "array":
|
|
10983
|
+
return parsed.arrayType === "string" ? [...DEFAULT_VALUES["string[]"]] : [...DEFAULT_VALUES["number[]"]];
|
|
10984
|
+
case "vector":
|
|
10985
|
+
return DEFAULT_VALUES.vector;
|
|
10986
|
+
default:
|
|
10987
|
+
return null;
|
|
10268
10988
|
}
|
|
10269
|
-
|
|
10270
|
-
|
|
10271
|
-
|
|
10272
|
-
|
|
10989
|
+
}
|
|
10990
|
+
function parseSchema(definition) {
|
|
10991
|
+
const columns = Object.keys(definition);
|
|
10992
|
+
const vectorColumns = [];
|
|
10993
|
+
const parsedTypes = new Map;
|
|
10994
|
+
for (const col of columns) {
|
|
10995
|
+
const parsed = parseColumnType(definition[col]);
|
|
10996
|
+
parsedTypes.set(col, parsed);
|
|
10997
|
+
if (parsed.baseType === "vector") {
|
|
10998
|
+
vectorColumns.push(col);
|
|
10273
10999
|
}
|
|
10274
|
-
return index.get(value) || [];
|
|
10275
11000
|
}
|
|
10276
|
-
|
|
10277
|
-
|
|
10278
|
-
|
|
10279
|
-
|
|
10280
|
-
|
|
10281
|
-
|
|
11001
|
+
return {
|
|
11002
|
+
definition,
|
|
11003
|
+
columns,
|
|
11004
|
+
vectorColumns,
|
|
11005
|
+
parsedTypes
|
|
11006
|
+
};
|
|
11007
|
+
}
|
|
11008
|
+
function createColumns(definition) {
|
|
11009
|
+
const schema = parseSchema(definition);
|
|
11010
|
+
const columns = new Map;
|
|
11011
|
+
for (const col of schema.columns) {
|
|
11012
|
+
columns.set(col, signal([]));
|
|
11013
|
+
}
|
|
11014
|
+
const manager = {
|
|
11015
|
+
schema,
|
|
11016
|
+
getColumn(name) {
|
|
11017
|
+
const col = columns.get(name);
|
|
11018
|
+
if (!col) {
|
|
11019
|
+
throw new Error(`Unknown column: ${String(name)}`);
|
|
11020
|
+
}
|
|
11021
|
+
return col;
|
|
11022
|
+
},
|
|
11023
|
+
get(column, index) {
|
|
11024
|
+
const col = columns.get(column);
|
|
11025
|
+
if (!col) {
|
|
11026
|
+
throw new Error(`Unknown column: ${String(column)}`);
|
|
11027
|
+
}
|
|
11028
|
+
return col.value[index];
|
|
11029
|
+
},
|
|
11030
|
+
set(column, index, value) {
|
|
11031
|
+
const col = columns.get(column);
|
|
11032
|
+
if (!col) {
|
|
11033
|
+
throw new Error(`Unknown column: ${String(column)}`);
|
|
11034
|
+
}
|
|
11035
|
+
const parsed = schema.parsedTypes.get(column);
|
|
11036
|
+
if (parsed?.baseType === "vector" && Array.isArray(value)) {
|
|
11037
|
+
value = new Float32Array(value);
|
|
11038
|
+
}
|
|
11039
|
+
const arr = col.value;
|
|
11040
|
+
while (arr.length <= index) {
|
|
11041
|
+
arr.push(getDefaultValue(definition[column]));
|
|
11042
|
+
}
|
|
11043
|
+
arr[index] = value;
|
|
11044
|
+
col.value = arr;
|
|
11045
|
+
},
|
|
11046
|
+
getRecord(index) {
|
|
11047
|
+
const record = {};
|
|
11048
|
+
for (const col of schema.columns) {
|
|
11049
|
+
record[col] = manager.get(col, index);
|
|
11050
|
+
}
|
|
11051
|
+
return record;
|
|
11052
|
+
},
|
|
11053
|
+
setRecord(index, record) {
|
|
11054
|
+
for (const col of schema.columns) {
|
|
11055
|
+
if (col in record) {
|
|
11056
|
+
manager.set(col, index, record[col]);
|
|
11057
|
+
} else {
|
|
11058
|
+
const defaultValue = getDefaultValue(definition[col]);
|
|
11059
|
+
manager.set(col, index, defaultValue);
|
|
11060
|
+
}
|
|
11061
|
+
}
|
|
11062
|
+
},
|
|
11063
|
+
clearAt(index) {
|
|
11064
|
+
for (const col of schema.columns) {
|
|
11065
|
+
const defaultValue = getDefaultValue(definition[col]);
|
|
11066
|
+
manager.set(col, index, defaultValue);
|
|
11067
|
+
}
|
|
11068
|
+
},
|
|
11069
|
+
reset() {
|
|
11070
|
+
for (const col of schema.columns) {
|
|
11071
|
+
const colSignal = columns.get(col);
|
|
11072
|
+
if (colSignal) {
|
|
11073
|
+
colSignal.value = [];
|
|
11074
|
+
}
|
|
10282
11075
|
}
|
|
10283
11076
|
}
|
|
10284
|
-
|
|
11077
|
+
};
|
|
11078
|
+
return manager;
|
|
11079
|
+
}
|
|
11080
|
+
function createMetadataArrays() {
|
|
11081
|
+
return {
|
|
11082
|
+
created: signal([]),
|
|
11083
|
+
updated: signal([]),
|
|
11084
|
+
stale: signal([])
|
|
11085
|
+
};
|
|
11086
|
+
}
|
|
11087
|
+
function createCollection(name, options) {
|
|
11088
|
+
const { schema, contentColumn } = options;
|
|
11089
|
+
const registry = createRegistry();
|
|
11090
|
+
const columns = createColumns(schema);
|
|
11091
|
+
const metadata = createMetadataArrays();
|
|
11092
|
+
function buildRecord(index) {
|
|
11093
|
+
const id = registry.getId(index);
|
|
11094
|
+
if (!id)
|
|
11095
|
+
throw new Error(`No ID for index ${index}`);
|
|
11096
|
+
const data = columns.getRecord(index);
|
|
11097
|
+
return {
|
|
11098
|
+
...data,
|
|
11099
|
+
id,
|
|
11100
|
+
created: metadata.created.value[index] ?? 0,
|
|
11101
|
+
updated: metadata.updated.value[index] ?? 0,
|
|
11102
|
+
stale: metadata.stale.value[index] ?? false
|
|
11103
|
+
};
|
|
10285
11104
|
}
|
|
10286
|
-
|
|
10287
|
-
const
|
|
10288
|
-
|
|
11105
|
+
function setMetadataAt(index, created, updated, stale) {
|
|
11106
|
+
const createdArr = metadata.created.value;
|
|
11107
|
+
const updatedArr = metadata.updated.value;
|
|
11108
|
+
const staleArr = metadata.stale.value;
|
|
11109
|
+
while (createdArr.length <= index)
|
|
11110
|
+
createdArr.push(0);
|
|
11111
|
+
while (updatedArr.length <= index)
|
|
11112
|
+
updatedArr.push(0);
|
|
11113
|
+
while (staleArr.length <= index)
|
|
11114
|
+
staleArr.push(false);
|
|
11115
|
+
createdArr[index] = created;
|
|
11116
|
+
updatedArr[index] = updated;
|
|
11117
|
+
staleArr[index] = stale;
|
|
11118
|
+
metadata.created.value = createdArr;
|
|
11119
|
+
metadata.updated.value = updatedArr;
|
|
11120
|
+
metadata.stale.value = staleArr;
|
|
11121
|
+
}
|
|
11122
|
+
const collection = {
|
|
11123
|
+
name,
|
|
11124
|
+
schema,
|
|
11125
|
+
contentColumn,
|
|
11126
|
+
registry,
|
|
11127
|
+
columns,
|
|
11128
|
+
insert(data) {
|
|
11129
|
+
const id = data.id ?? generateId();
|
|
11130
|
+
const index = registry.allocate(id);
|
|
11131
|
+
const now = Date.now();
|
|
11132
|
+
columns.setRecord(index, data);
|
|
11133
|
+
setMetadataAt(index, now, now, false);
|
|
11134
|
+
return id;
|
|
11135
|
+
},
|
|
11136
|
+
insertMany(records) {
|
|
11137
|
+
return records.map((record) => collection.insert(record));
|
|
11138
|
+
},
|
|
11139
|
+
get(id) {
|
|
11140
|
+
const index = registry.getIndex(id);
|
|
11141
|
+
if (index === -1)
|
|
11142
|
+
return;
|
|
11143
|
+
return buildRecord(index);
|
|
11144
|
+
},
|
|
11145
|
+
all() {
|
|
11146
|
+
const indices = registry.getAllIndices();
|
|
11147
|
+
return indices.map((index) => buildRecord(index));
|
|
11148
|
+
},
|
|
11149
|
+
find(filter) {
|
|
11150
|
+
const results = [];
|
|
11151
|
+
const indices = registry.getAllIndices();
|
|
11152
|
+
for (const index of indices) {
|
|
11153
|
+
const data = columns.getRecord(index);
|
|
11154
|
+
if (filter(data, index)) {
|
|
11155
|
+
results.push(buildRecord(index));
|
|
11156
|
+
}
|
|
11157
|
+
}
|
|
11158
|
+
return results;
|
|
11159
|
+
},
|
|
11160
|
+
findOne(filter) {
|
|
11161
|
+
const indices = registry.getAllIndices();
|
|
11162
|
+
for (const index of indices) {
|
|
11163
|
+
const data = columns.getRecord(index);
|
|
11164
|
+
if (filter(data, index)) {
|
|
11165
|
+
return buildRecord(index);
|
|
11166
|
+
}
|
|
11167
|
+
}
|
|
10289
11168
|
return;
|
|
10290
|
-
|
|
10291
|
-
|
|
10292
|
-
|
|
10293
|
-
|
|
10294
|
-
|
|
10295
|
-
|
|
11169
|
+
},
|
|
11170
|
+
update(id, data) {
|
|
11171
|
+
const index = registry.getIndex(id);
|
|
11172
|
+
if (index === -1)
|
|
11173
|
+
return false;
|
|
11174
|
+
for (const key of Object.keys(data)) {
|
|
11175
|
+
columns.set(key, index, data[key]);
|
|
11176
|
+
}
|
|
11177
|
+
const updatedArr = metadata.updated.value;
|
|
11178
|
+
updatedArr[index] = Date.now();
|
|
11179
|
+
metadata.updated.value = updatedArr;
|
|
11180
|
+
return true;
|
|
11181
|
+
},
|
|
11182
|
+
updateField(id, field, value) {
|
|
11183
|
+
const index = registry.getIndex(id);
|
|
11184
|
+
if (index === -1)
|
|
11185
|
+
return false;
|
|
11186
|
+
columns.set(field, index, value);
|
|
11187
|
+
const updatedArr = metadata.updated.value;
|
|
11188
|
+
updatedArr[index] = Date.now();
|
|
11189
|
+
metadata.updated.value = updatedArr;
|
|
11190
|
+
return true;
|
|
11191
|
+
},
|
|
11192
|
+
updateMany(filter, data) {
|
|
11193
|
+
let count = 0;
|
|
11194
|
+
const indices = registry.getAllIndices();
|
|
11195
|
+
const now = Date.now();
|
|
11196
|
+
for (const index of indices) {
|
|
11197
|
+
const record = columns.getRecord(index);
|
|
11198
|
+
if (filter(record, index)) {
|
|
11199
|
+
for (const key of Object.keys(data)) {
|
|
11200
|
+
columns.set(key, index, data[key]);
|
|
11201
|
+
}
|
|
11202
|
+
const updatedArr = metadata.updated.value;
|
|
11203
|
+
updatedArr[index] = now;
|
|
11204
|
+
metadata.updated.value = updatedArr;
|
|
11205
|
+
count++;
|
|
10296
11206
|
}
|
|
10297
|
-
break;
|
|
10298
11207
|
}
|
|
10299
|
-
|
|
10300
|
-
|
|
10301
|
-
|
|
10302
|
-
|
|
11208
|
+
return count;
|
|
11209
|
+
},
|
|
11210
|
+
delete(id) {
|
|
11211
|
+
const index = registry.getIndex(id);
|
|
11212
|
+
if (index === -1)
|
|
11213
|
+
return false;
|
|
11214
|
+
columns.clearAt(index);
|
|
11215
|
+
const createdArr = metadata.created.value;
|
|
11216
|
+
const updatedArr = metadata.updated.value;
|
|
11217
|
+
const staleArr = metadata.stale.value;
|
|
11218
|
+
if (index < createdArr.length)
|
|
11219
|
+
createdArr[index] = 0;
|
|
11220
|
+
if (index < updatedArr.length)
|
|
11221
|
+
updatedArr[index] = 0;
|
|
11222
|
+
if (index < staleArr.length)
|
|
11223
|
+
staleArr[index] = false;
|
|
11224
|
+
metadata.created.value = createdArr;
|
|
11225
|
+
metadata.updated.value = updatedArr;
|
|
11226
|
+
metadata.stale.value = staleArr;
|
|
11227
|
+
registry.release(id);
|
|
11228
|
+
return true;
|
|
11229
|
+
},
|
|
11230
|
+
deleteMany(filter) {
|
|
11231
|
+
const toDelete = [];
|
|
11232
|
+
const indices = registry.getAllIndices();
|
|
11233
|
+
for (const index of indices) {
|
|
11234
|
+
const data = columns.getRecord(index);
|
|
11235
|
+
if (filter(data, index)) {
|
|
11236
|
+
const id = registry.getId(index);
|
|
11237
|
+
if (id)
|
|
11238
|
+
toDelete.push(id);
|
|
11239
|
+
}
|
|
10303
11240
|
}
|
|
10304
|
-
|
|
11241
|
+
for (const id of toDelete) {
|
|
11242
|
+
collection.delete(id);
|
|
11243
|
+
}
|
|
11244
|
+
return toDelete.length;
|
|
11245
|
+
},
|
|
11246
|
+
count(filter) {
|
|
11247
|
+
if (!filter) {
|
|
11248
|
+
return registry.count;
|
|
11249
|
+
}
|
|
11250
|
+
let count = 0;
|
|
11251
|
+
const indices = registry.getAllIndices();
|
|
11252
|
+
for (const index of indices) {
|
|
11253
|
+
const data = columns.getRecord(index);
|
|
11254
|
+
if (filter(data, index))
|
|
11255
|
+
count++;
|
|
11256
|
+
}
|
|
11257
|
+
return count;
|
|
11258
|
+
},
|
|
11259
|
+
reactiveCount: derived(() => registry.count),
|
|
11260
|
+
getByIndex(index) {
|
|
11261
|
+
if (!registry.allocatedIndices.has(index))
|
|
11262
|
+
return;
|
|
11263
|
+
return buildRecord(index);
|
|
11264
|
+
},
|
|
11265
|
+
getIndices() {
|
|
11266
|
+
return registry.getAllIndices();
|
|
11267
|
+
},
|
|
11268
|
+
has(id) {
|
|
11269
|
+
return registry.has(id);
|
|
11270
|
+
},
|
|
11271
|
+
isStale(id) {
|
|
11272
|
+
const index = registry.getIndex(id);
|
|
11273
|
+
if (index === -1)
|
|
11274
|
+
return false;
|
|
11275
|
+
return metadata.stale.value[index] ?? false;
|
|
11276
|
+
},
|
|
11277
|
+
getStaleIds() {
|
|
11278
|
+
const ids = [];
|
|
11279
|
+
const staleArr = metadata.stale.value;
|
|
11280
|
+
for (const index of registry.getAllIndices()) {
|
|
11281
|
+
if (staleArr[index]) {
|
|
11282
|
+
const id = registry.getId(index);
|
|
11283
|
+
if (id)
|
|
11284
|
+
ids.push(id);
|
|
11285
|
+
}
|
|
11286
|
+
}
|
|
11287
|
+
return ids;
|
|
11288
|
+
},
|
|
11289
|
+
setStale(id, stale) {
|
|
11290
|
+
const index = registry.getIndex(id);
|
|
11291
|
+
if (index === -1)
|
|
11292
|
+
return;
|
|
11293
|
+
const staleArr = metadata.stale.value;
|
|
11294
|
+
while (staleArr.length <= index)
|
|
11295
|
+
staleArr.push(false);
|
|
11296
|
+
staleArr[index] = stale;
|
|
11297
|
+
metadata.stale.value = staleArr;
|
|
11298
|
+
},
|
|
11299
|
+
setMetadata(id, created, updated, stale = false) {
|
|
11300
|
+
const index = registry.getIndex(id);
|
|
11301
|
+
if (index === -1)
|
|
11302
|
+
return;
|
|
11303
|
+
setMetadataAt(index, created, updated, stale);
|
|
11304
|
+
},
|
|
11305
|
+
clear() {
|
|
11306
|
+
registry.reset();
|
|
11307
|
+
columns.reset();
|
|
11308
|
+
metadata.created.value = [];
|
|
11309
|
+
metadata.updated.value = [];
|
|
11310
|
+
metadata.stale.value = [];
|
|
10305
11311
|
}
|
|
11312
|
+
};
|
|
11313
|
+
return collection;
|
|
11314
|
+
}
|
|
11315
|
+
function idToFilename(id) {
|
|
11316
|
+
return id.replace(/[<>:"/\\|?*\x00-\x1f]/g, "_") + ".md";
|
|
11317
|
+
}
|
|
11318
|
+
function filenameToId(filename) {
|
|
11319
|
+
return filename.replace(/\.md$/, "");
|
|
11320
|
+
}
|
|
11321
|
+
function parseMarkdown(text) {
|
|
11322
|
+
const frontmatter = {};
|
|
11323
|
+
let content = "";
|
|
11324
|
+
if (!text.startsWith("---")) {
|
|
11325
|
+
return { frontmatter, content: text.trim() };
|
|
10306
11326
|
}
|
|
10307
|
-
|
|
10308
|
-
|
|
10309
|
-
|
|
10310
|
-
|
|
10311
|
-
return this._indexes.has(column);
|
|
11327
|
+
const endIndex = text.indexOf(`
|
|
11328
|
+
---`, 3);
|
|
11329
|
+
if (endIndex === -1) {
|
|
11330
|
+
return { frontmatter, content: text.trim() };
|
|
10312
11331
|
}
|
|
10313
|
-
|
|
10314
|
-
|
|
10315
|
-
const result = {};
|
|
10316
|
-
const lines = text.split(`
|
|
11332
|
+
const yamlText = text.slice(4, endIndex);
|
|
11333
|
+
const lines = yamlText.split(`
|
|
10317
11334
|
`);
|
|
10318
11335
|
for (const line of lines) {
|
|
10319
11336
|
const trimmed = line.trim();
|
|
10320
|
-
if (!trimmed || trimmed
|
|
11337
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
10321
11338
|
continue;
|
|
10322
11339
|
const colonIndex = trimmed.indexOf(":");
|
|
10323
11340
|
if (colonIndex === -1)
|
|
10324
11341
|
continue;
|
|
10325
11342
|
const key = trimmed.slice(0, colonIndex).trim();
|
|
10326
11343
|
let value = trimmed.slice(colonIndex + 1).trim();
|
|
10327
|
-
|
|
11344
|
+
frontmatter[key] = parseYamlValue(value);
|
|
10328
11345
|
}
|
|
10329
|
-
|
|
11346
|
+
content = text.slice(endIndex + 4).trim();
|
|
11347
|
+
return { frontmatter, content };
|
|
10330
11348
|
}
|
|
10331
|
-
function
|
|
10332
|
-
if (
|
|
10333
|
-
return
|
|
11349
|
+
function parseYamlValue(value) {
|
|
11350
|
+
if (value === "null" || value === "~" || value === "") {
|
|
11351
|
+
return null;
|
|
11352
|
+
}
|
|
10334
11353
|
if (value === "true")
|
|
10335
11354
|
return true;
|
|
10336
11355
|
if (value === "false")
|
|
10337
11356
|
return false;
|
|
11357
|
+
if (/^-?\d+$/.test(value)) {
|
|
11358
|
+
return parseInt(value, 10);
|
|
11359
|
+
}
|
|
11360
|
+
if (/^-?\d+\.\d+$/.test(value)) {
|
|
11361
|
+
return parseFloat(value);
|
|
11362
|
+
}
|
|
10338
11363
|
if (value.startsWith("[") && value.endsWith("]")) {
|
|
10339
|
-
|
|
10340
|
-
|
|
10341
|
-
|
|
10342
|
-
|
|
10343
|
-
const firstItem = items[0];
|
|
10344
|
-
if (firstItem && !isNaN(Number(firstItem))) {
|
|
10345
|
-
return items.map((s) => Number(s));
|
|
11364
|
+
try {
|
|
11365
|
+
return JSON.parse(value);
|
|
11366
|
+
} catch {
|
|
11367
|
+
return value;
|
|
10346
11368
|
}
|
|
10347
|
-
return items.map((s) => s.replace(/^["']|["']$/g, ""));
|
|
10348
11369
|
}
|
|
10349
|
-
if (
|
|
10350
|
-
return
|
|
11370
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
11371
|
+
return value.slice(1, -1);
|
|
10351
11372
|
}
|
|
10352
|
-
return value
|
|
11373
|
+
return value;
|
|
10353
11374
|
}
|
|
10354
|
-
function
|
|
10355
|
-
if (value ===
|
|
10356
|
-
return "";
|
|
10357
|
-
if (value instanceof Float32Array) {
|
|
10358
|
-
return `[${Array.from(value).join(", ")}]`;
|
|
10359
|
-
}
|
|
10360
|
-
if (Array.isArray(value)) {
|
|
10361
|
-
if (value.length === 0)
|
|
10362
|
-
return "[]";
|
|
10363
|
-
if (typeof value[0] === "number") {
|
|
10364
|
-
return `[${value.join(", ")}]`;
|
|
10365
|
-
}
|
|
10366
|
-
return `[${value.map((v) => `"${v}"`).join(", ")}]`;
|
|
11375
|
+
function toYamlValue(value) {
|
|
11376
|
+
if (value === null || value === undefined) {
|
|
11377
|
+
return "null";
|
|
10367
11378
|
}
|
|
10368
11379
|
if (typeof value === "boolean") {
|
|
10369
11380
|
return value ? "true" : "false";
|
|
@@ -10371,746 +11382,618 @@ function serializeValue(value, type) {
|
|
|
10371
11382
|
if (typeof value === "number") {
|
|
10372
11383
|
return String(value);
|
|
10373
11384
|
}
|
|
10374
|
-
|
|
11385
|
+
if (Array.isArray(value)) {
|
|
11386
|
+
return JSON.stringify(value);
|
|
11387
|
+
}
|
|
11388
|
+
if (value instanceof Float32Array) {
|
|
11389
|
+
return JSON.stringify(Array.from(value));
|
|
11390
|
+
}
|
|
11391
|
+
if (typeof value === "string") {
|
|
11392
|
+
if (value.includes(":") || value.includes("#") || value.includes(`
|
|
11393
|
+
`) || value.startsWith('"') || value.startsWith("'") || value === "true" || value === "false" || value === "null") {
|
|
11394
|
+
return JSON.stringify(value);
|
|
11395
|
+
}
|
|
11396
|
+
return value;
|
|
11397
|
+
}
|
|
11398
|
+
return JSON.stringify(value);
|
|
10375
11399
|
}
|
|
10376
|
-
function
|
|
11400
|
+
function generateMarkdown(record, schema, contentColumn) {
|
|
10377
11401
|
const lines = ["---"];
|
|
10378
|
-
|
|
10379
|
-
|
|
11402
|
+
lines.push(`id: ${toYamlValue(record.id)}`);
|
|
11403
|
+
lines.push(`created: ${record.created}`);
|
|
11404
|
+
lines.push(`updated: ${record.updated}`);
|
|
11405
|
+
for (const key of Object.keys(schema)) {
|
|
11406
|
+
if (key === contentColumn)
|
|
10380
11407
|
continue;
|
|
10381
|
-
const
|
|
10382
|
-
lines.push(`${key}: ${
|
|
11408
|
+
const value = record[key];
|
|
11409
|
+
lines.push(`${String(key)}: ${toYamlValue(value)}`);
|
|
10383
11410
|
}
|
|
10384
11411
|
lines.push("---");
|
|
10385
|
-
|
|
10386
|
-
|
|
10387
|
-
|
|
10388
|
-
|
|
10389
|
-
|
|
10390
|
-
`);
|
|
10391
|
-
let inFrontmatter = false;
|
|
10392
|
-
let frontmatterStart = -1;
|
|
10393
|
-
let frontmatterEnd = -1;
|
|
10394
|
-
for (let i = 0;i < lines.length; i++) {
|
|
10395
|
-
const line = lines[i].trim();
|
|
10396
|
-
if (line === "---") {
|
|
10397
|
-
if (!inFrontmatter) {
|
|
10398
|
-
inFrontmatter = true;
|
|
10399
|
-
frontmatterStart = i;
|
|
10400
|
-
} else {
|
|
10401
|
-
frontmatterEnd = i;
|
|
10402
|
-
break;
|
|
10403
|
-
}
|
|
11412
|
+
lines.push("");
|
|
11413
|
+
if (contentColumn) {
|
|
11414
|
+
const content = record[contentColumn];
|
|
11415
|
+
if (typeof content === "string") {
|
|
11416
|
+
lines.push(content);
|
|
10404
11417
|
}
|
|
10405
11418
|
}
|
|
10406
|
-
|
|
10407
|
-
return {
|
|
10408
|
-
id: "",
|
|
10409
|
-
frontmatter: {},
|
|
10410
|
-
content: content.trim()
|
|
10411
|
-
};
|
|
10412
|
-
}
|
|
10413
|
-
const frontmatterText = lines.slice(frontmatterStart + 1, frontmatterEnd).join(`
|
|
11419
|
+
return lines.join(`
|
|
10414
11420
|
`);
|
|
10415
|
-
const frontmatter = parseFrontmatter(frontmatterText);
|
|
10416
|
-
const contentLines = lines.slice(frontmatterEnd + 1);
|
|
10417
|
-
const contentText = contentLines.join(`
|
|
10418
|
-
`).trim();
|
|
10419
|
-
return {
|
|
10420
|
-
id: frontmatter.id || "",
|
|
10421
|
-
frontmatter,
|
|
10422
|
-
content: contentText
|
|
10423
|
-
};
|
|
10424
|
-
}
|
|
10425
|
-
function generateMarkdown(record, content, schema) {
|
|
10426
|
-
const frontmatter = generateFrontmatter(record, schema);
|
|
10427
|
-
return `${frontmatter}
|
|
10428
|
-
|
|
10429
|
-
${content}`;
|
|
10430
|
-
}
|
|
10431
|
-
async function loadFromMarkdown(filePath) {
|
|
10432
|
-
const content = await Bun.file(filePath).text();
|
|
10433
|
-
return parseMarkdown(content);
|
|
10434
|
-
}
|
|
10435
|
-
async function saveToMarkdown(filePath, record, content, schema) {
|
|
10436
|
-
const markdown = generateMarkdown(record, content, schema);
|
|
10437
|
-
await Bun.write(filePath, markdown);
|
|
10438
|
-
}
|
|
10439
|
-
async function loadFromDirectory(dirPath) {
|
|
10440
|
-
const glob = new Bun.Glob("**/*.md");
|
|
10441
|
-
const documents = [];
|
|
10442
|
-
for await (const file of glob.scan({ cwd: dirPath, absolute: true })) {
|
|
10443
|
-
try {
|
|
10444
|
-
const doc = await loadFromMarkdown(file);
|
|
10445
|
-
documents.push(doc);
|
|
10446
|
-
} catch (error) {
|
|
10447
|
-
console.error(`Failed to load ${file}:`, error);
|
|
10448
|
-
}
|
|
10449
|
-
}
|
|
10450
|
-
return documents;
|
|
10451
|
-
}
|
|
10452
|
-
function idToFilename(id) {
|
|
10453
|
-
return id.replace(/[^a-zA-Z0-9-_]/g, "_") + ".md";
|
|
10454
11421
|
}
|
|
10455
|
-
function
|
|
10456
|
-
|
|
10457
|
-
}
|
|
10458
|
-
|
|
10459
|
-
class FileWatcher {
|
|
10460
|
-
_path;
|
|
10461
|
-
_watcher = null;
|
|
10462
|
-
_handler;
|
|
10463
|
-
_options;
|
|
10464
|
-
_debounceTimers = new Map;
|
|
10465
|
-
_knownFiles = new Set;
|
|
10466
|
-
_isStarting = false;
|
|
10467
|
-
constructor(path, handler, options = {}) {
|
|
10468
|
-
this._path = path;
|
|
10469
|
-
this._handler = handler;
|
|
10470
|
-
this._options = {
|
|
10471
|
-
debounceMs: options.debounceMs ?? 100,
|
|
10472
|
-
extension: options.extension ?? ".md"
|
|
10473
|
-
};
|
|
10474
|
-
}
|
|
10475
|
-
async start() {
|
|
10476
|
-
if (this._watcher || this._isStarting)
|
|
10477
|
-
return;
|
|
10478
|
-
this._isStarting = true;
|
|
10479
|
-
await this._scanExistingFiles();
|
|
10480
|
-
this._watcher = import_fs.watch(this._path, { recursive: false }, (eventType, filename) => {
|
|
10481
|
-
if (!filename)
|
|
10482
|
-
return;
|
|
10483
|
-
if (!filename.endsWith(this._options.extension))
|
|
10484
|
-
return;
|
|
10485
|
-
this._handleChange(eventType, filename);
|
|
10486
|
-
});
|
|
10487
|
-
this._isStarting = false;
|
|
10488
|
-
}
|
|
10489
|
-
stop() {
|
|
10490
|
-
if (this._watcher) {
|
|
10491
|
-
this._watcher.close();
|
|
10492
|
-
this._watcher = null;
|
|
10493
|
-
}
|
|
10494
|
-
for (const timer of this._debounceTimers.values()) {
|
|
10495
|
-
clearTimeout(timer);
|
|
10496
|
-
}
|
|
10497
|
-
this._debounceTimers.clear();
|
|
10498
|
-
}
|
|
10499
|
-
get isWatching() {
|
|
10500
|
-
return this._watcher !== null;
|
|
10501
|
-
}
|
|
10502
|
-
async _scanExistingFiles() {
|
|
10503
|
-
try {
|
|
10504
|
-
const glob = new Bun.Glob(`*${this._options.extension}`);
|
|
10505
|
-
for await (const file of glob.scan({ cwd: this._path, absolute: false })) {
|
|
10506
|
-
this._knownFiles.add(file);
|
|
10507
|
-
}
|
|
10508
|
-
} catch (error) {
|
|
10509
|
-
console.warn(`FileWatcher: Could not scan ${this._path}:`, error);
|
|
10510
|
-
}
|
|
10511
|
-
}
|
|
10512
|
-
_handleChange(eventType, filename) {
|
|
10513
|
-
const existingTimer = this._debounceTimers.get(filename);
|
|
10514
|
-
if (existingTimer) {
|
|
10515
|
-
clearTimeout(existingTimer);
|
|
10516
|
-
}
|
|
10517
|
-
const timer = setTimeout(async () => {
|
|
10518
|
-
this._debounceTimers.delete(filename);
|
|
10519
|
-
await this._processChange(filename);
|
|
10520
|
-
}, this._options.debounceMs);
|
|
10521
|
-
this._debounceTimers.set(filename, timer);
|
|
10522
|
-
}
|
|
10523
|
-
async _processChange(filename) {
|
|
10524
|
-
const filepath = import_path.join(this._path, filename);
|
|
10525
|
-
const id = filenameToId(filename);
|
|
11422
|
+
async function loadFromMarkdown(filepath, schema, contentColumn) {
|
|
11423
|
+
try {
|
|
10526
11424
|
const file = Bun.file(filepath);
|
|
10527
|
-
|
|
10528
|
-
|
|
10529
|
-
if (!exists) {
|
|
10530
|
-
if (this._knownFiles.has(filename)) {
|
|
10531
|
-
changeType = "delete";
|
|
10532
|
-
this._knownFiles.delete(filename);
|
|
10533
|
-
} else {
|
|
10534
|
-
return;
|
|
10535
|
-
}
|
|
10536
|
-
} else if (this._knownFiles.has(filename)) {
|
|
10537
|
-
changeType = "update";
|
|
10538
|
-
} else {
|
|
10539
|
-
changeType = "create";
|
|
10540
|
-
this._knownFiles.add(filename);
|
|
11425
|
+
if (!await file.exists()) {
|
|
11426
|
+
return null;
|
|
10541
11427
|
}
|
|
10542
|
-
|
|
10543
|
-
|
|
10544
|
-
|
|
10545
|
-
|
|
10546
|
-
|
|
10547
|
-
|
|
10548
|
-
});
|
|
10549
|
-
} catch (error) {
|
|
10550
|
-
console.error(`FileWatcher: Error handling ${changeType} for ${filename}:`, error);
|
|
10551
|
-
}
|
|
10552
|
-
}
|
|
10553
|
-
async rescan() {
|
|
10554
|
-
const previousFiles = new Set(this._knownFiles);
|
|
10555
|
-
this._knownFiles.clear();
|
|
10556
|
-
await this._scanExistingFiles();
|
|
10557
|
-
for (const filename of this._knownFiles) {
|
|
10558
|
-
if (!previousFiles.has(filename)) {
|
|
10559
|
-
const filepath = import_path.join(this._path, filename);
|
|
10560
|
-
const id = filenameToId(filename);
|
|
10561
|
-
await this._handler({
|
|
10562
|
-
type: "create",
|
|
10563
|
-
id,
|
|
10564
|
-
filename,
|
|
10565
|
-
filepath
|
|
10566
|
-
});
|
|
10567
|
-
}
|
|
11428
|
+
const text = await file.text();
|
|
11429
|
+
const { frontmatter, content } = parseMarkdown(text);
|
|
11430
|
+
const id = frontmatter.id;
|
|
11431
|
+
if (!id) {
|
|
11432
|
+
const filename = filepath.split("/").pop() || "";
|
|
11433
|
+
return null;
|
|
10568
11434
|
}
|
|
10569
|
-
|
|
10570
|
-
|
|
10571
|
-
|
|
10572
|
-
|
|
10573
|
-
|
|
10574
|
-
|
|
10575
|
-
|
|
10576
|
-
|
|
10577
|
-
|
|
10578
|
-
|
|
11435
|
+
const record = {
|
|
11436
|
+
id,
|
|
11437
|
+
created: frontmatter.created || Date.now(),
|
|
11438
|
+
updated: frontmatter.updated || Date.now(),
|
|
11439
|
+
stale: false
|
|
11440
|
+
};
|
|
11441
|
+
for (const key of Object.keys(schema)) {
|
|
11442
|
+
if (key === contentColumn) {
|
|
11443
|
+
record[key] = content;
|
|
11444
|
+
} else if (key in frontmatter) {
|
|
11445
|
+
let value = frontmatter[key];
|
|
11446
|
+
const parsed = parseColumnType(schema[key]);
|
|
11447
|
+
if (parsed.baseType === "vector" && Array.isArray(value)) {
|
|
11448
|
+
value = new Float32Array(value);
|
|
11449
|
+
}
|
|
11450
|
+
record[key] = value;
|
|
10579
11451
|
}
|
|
10580
11452
|
}
|
|
11453
|
+
return { id, record };
|
|
11454
|
+
} catch {
|
|
11455
|
+
return null;
|
|
10581
11456
|
}
|
|
10582
11457
|
}
|
|
10583
|
-
function
|
|
10584
|
-
|
|
10585
|
-
|
|
11458
|
+
async function saveToMarkdown(filepath, record, schema, contentColumn) {
|
|
11459
|
+
try {
|
|
11460
|
+
const markdown = generateMarkdown(record, schema, contentColumn);
|
|
11461
|
+
await Bun.write(filepath, markdown);
|
|
11462
|
+
return true;
|
|
11463
|
+
} catch {
|
|
11464
|
+
return false;
|
|
10586
11465
|
}
|
|
10587
|
-
let dotProduct = 0;
|
|
10588
|
-
let normA = 0;
|
|
10589
|
-
let normB = 0;
|
|
10590
|
-
for (let i = 0;i < a.length; i++) {
|
|
10591
|
-
const ai = a[i];
|
|
10592
|
-
const bi = b[i];
|
|
10593
|
-
dotProduct += ai * bi;
|
|
10594
|
-
normA += ai * ai;
|
|
10595
|
-
normB += bi * bi;
|
|
10596
|
-
}
|
|
10597
|
-
const magnitude = Math.sqrt(normA) * Math.sqrt(normB);
|
|
10598
|
-
if (magnitude === 0)
|
|
10599
|
-
return 0;
|
|
10600
|
-
return dotProduct / magnitude;
|
|
10601
11466
|
}
|
|
10602
|
-
function
|
|
11467
|
+
async function loadFromDirectory(dirpath, schema, contentColumn) {
|
|
10603
11468
|
const results = [];
|
|
10604
|
-
|
|
10605
|
-
|
|
10606
|
-
|
|
10607
|
-
|
|
10608
|
-
|
|
10609
|
-
|
|
10610
|
-
|
|
10611
|
-
|
|
10612
|
-
const vector = vectors[idx];
|
|
10613
|
-
if (!vector)
|
|
10614
|
-
continue;
|
|
10615
|
-
let dotProduct = 0;
|
|
10616
|
-
let vectorNorm = 0;
|
|
10617
|
-
for (let i = 0;i < query.length; i++) {
|
|
10618
|
-
const vi = vector[i];
|
|
10619
|
-
dotProduct += query[i] * vi;
|
|
10620
|
-
vectorNorm += vi * vi;
|
|
10621
|
-
}
|
|
10622
|
-
vectorNorm = Math.sqrt(vectorNorm);
|
|
10623
|
-
if (vectorNorm === 0)
|
|
10624
|
-
continue;
|
|
10625
|
-
const similarity = dotProduct / (queryNorm * vectorNorm);
|
|
10626
|
-
results.push({ index: idx, similarity });
|
|
10627
|
-
}
|
|
10628
|
-
results.sort((a, b) => b.similarity - a.similarity);
|
|
10629
|
-
if (topK !== undefined && topK > 0) {
|
|
10630
|
-
return results.slice(0, topK);
|
|
10631
|
-
}
|
|
10632
|
-
return results;
|
|
10633
|
-
}
|
|
10634
|
-
function vectorSearch(vectors, indices, query, options = {}) {
|
|
10635
|
-
const { topK, minSimilarity = 0 } = options;
|
|
10636
|
-
let results = batchCosineSimilarity(query, vectors, indices, topK);
|
|
10637
|
-
if (minSimilarity > 0) {
|
|
10638
|
-
results = results.filter((r) => r.similarity >= minSimilarity);
|
|
10639
|
-
}
|
|
10640
|
-
return results;
|
|
10641
|
-
}
|
|
10642
|
-
function toFloat32Array(arr) {
|
|
10643
|
-
return new Float32Array(arr);
|
|
10644
|
-
}
|
|
10645
|
-
|
|
10646
|
-
class Database {
|
|
10647
|
-
_options;
|
|
10648
|
-
_columns;
|
|
10649
|
-
_schema;
|
|
10650
|
-
_contentColumn;
|
|
10651
|
-
_watcher = null;
|
|
10652
|
-
_isSaving = new Set;
|
|
10653
|
-
_created = [];
|
|
10654
|
-
_updated = [];
|
|
10655
|
-
_contentHashes = new ReactiveMap;
|
|
10656
|
-
_staleFlags = [];
|
|
10657
|
-
_onFileChange;
|
|
10658
|
-
constructor(options) {
|
|
10659
|
-
this._options = options;
|
|
10660
|
-
this._schema = createSchema(options.schema);
|
|
10661
|
-
this._columns = new Columns(options.schema);
|
|
10662
|
-
this._contentColumn = options.contentColumn;
|
|
10663
|
-
}
|
|
10664
|
-
onFileChange(callback) {
|
|
10665
|
-
this._onFileChange = callback;
|
|
10666
|
-
}
|
|
10667
|
-
setEmbedding(id, vectorColumn, embedding, sourceContent) {
|
|
10668
|
-
const index = getIndex(id);
|
|
10669
|
-
if (index === undefined)
|
|
10670
|
-
return false;
|
|
10671
|
-
const vector = Array.isArray(embedding) ? toFloat32Array(embedding) : embedding;
|
|
10672
|
-
this._columns.set(vectorColumn, index, vector);
|
|
10673
|
-
if (!this._contentHashes.has(vectorColumn)) {
|
|
10674
|
-
this._contentHashes.set(vectorColumn, []);
|
|
10675
|
-
}
|
|
10676
|
-
this._contentHashes.get(vectorColumn)[index] = Bun.hash(sourceContent);
|
|
10677
|
-
this._staleFlags[index] = false;
|
|
10678
|
-
return true;
|
|
10679
|
-
}
|
|
10680
|
-
isStale(id) {
|
|
10681
|
-
const index = getIndex(id);
|
|
10682
|
-
if (index === undefined)
|
|
10683
|
-
return false;
|
|
10684
|
-
return this._staleFlags[index] ?? false;
|
|
10685
|
-
}
|
|
10686
|
-
setStale(id, stale) {
|
|
10687
|
-
const index = getIndex(id);
|
|
10688
|
-
if (index === undefined)
|
|
10689
|
-
return;
|
|
10690
|
-
this._staleFlags[index] = stale;
|
|
10691
|
-
}
|
|
10692
|
-
getStaleIds() {
|
|
10693
|
-
const staleIds = [];
|
|
10694
|
-
for (const index of getAllIndices()) {
|
|
10695
|
-
if (this._staleFlags[index]) {
|
|
10696
|
-
const id = getId(index);
|
|
10697
|
-
if (id)
|
|
10698
|
-
staleIds.push(id);
|
|
10699
|
-
}
|
|
10700
|
-
}
|
|
10701
|
-
return staleIds;
|
|
10702
|
-
}
|
|
10703
|
-
async insert(data) {
|
|
10704
|
-
const id = data.id || this._generateId();
|
|
10705
|
-
const index = allocateIndex(id);
|
|
10706
|
-
const now = Date.now();
|
|
10707
|
-
this._created[index] = now;
|
|
10708
|
-
this._updated[index] = now;
|
|
10709
|
-
for (const [key, value] of Object.entries(data)) {
|
|
10710
|
-
if (key === "id")
|
|
10711
|
-
continue;
|
|
10712
|
-
const colType = this._options.schema[key];
|
|
10713
|
-
if (colType && typeof colType === "string" && colType.startsWith("vector:")) {
|
|
10714
|
-
if (Array.isArray(value)) {
|
|
10715
|
-
this._columns.set(key, index, toFloat32Array(value));
|
|
10716
|
-
} else {
|
|
10717
|
-
this._columns.set(key, index, value);
|
|
10718
|
-
}
|
|
10719
|
-
} else {
|
|
10720
|
-
this._columns.set(key, index, value);
|
|
10721
|
-
}
|
|
10722
|
-
}
|
|
10723
|
-
if (this._options.autoSave && this._options.path) {
|
|
10724
|
-
await this._saveRecord(id, index);
|
|
10725
|
-
}
|
|
10726
|
-
return id;
|
|
10727
|
-
}
|
|
10728
|
-
get(id) {
|
|
10729
|
-
const index = getIndex(id);
|
|
10730
|
-
if (index === undefined)
|
|
10731
|
-
return null;
|
|
10732
|
-
const record = this._columns.getRecord(index);
|
|
10733
|
-
return {
|
|
10734
|
-
id,
|
|
10735
|
-
...record,
|
|
10736
|
-
created: this._created[index] || 0,
|
|
10737
|
-
updated: this._updated[index] || 0,
|
|
10738
|
-
stale: this._staleFlags[index] ?? false
|
|
10739
|
-
};
|
|
10740
|
-
}
|
|
10741
|
-
async update(id, data) {
|
|
10742
|
-
const index = getIndex(id);
|
|
10743
|
-
if (index === undefined)
|
|
10744
|
-
return false;
|
|
10745
|
-
this._updated[index] = Date.now();
|
|
10746
|
-
for (const [key, value] of Object.entries(data)) {
|
|
10747
|
-
const colType = this._options.schema[key];
|
|
10748
|
-
if (colType && typeof colType === "string" && colType.startsWith("vector:")) {
|
|
10749
|
-
if (Array.isArray(value)) {
|
|
10750
|
-
this._columns.set(key, index, toFloat32Array(value));
|
|
10751
|
-
} else {
|
|
10752
|
-
this._columns.set(key, index, value);
|
|
10753
|
-
}
|
|
10754
|
-
} else {
|
|
10755
|
-
this._columns.set(key, index, value);
|
|
11469
|
+
try {
|
|
11470
|
+
const glob = new Bun.Glob("*.md");
|
|
11471
|
+
const files = glob.scanSync({ cwd: dirpath });
|
|
11472
|
+
for (const filename of files) {
|
|
11473
|
+
const filepath = `${dirpath}/${filename}`;
|
|
11474
|
+
const result = await loadFromMarkdown(filepath, schema, contentColumn);
|
|
11475
|
+
if (result) {
|
|
11476
|
+
results.push(result);
|
|
10756
11477
|
}
|
|
10757
11478
|
}
|
|
10758
|
-
|
|
10759
|
-
|
|
10760
|
-
|
|
11479
|
+
} catch {}
|
|
11480
|
+
return results;
|
|
11481
|
+
}
|
|
11482
|
+
async function deleteMarkdownFile(filepath) {
|
|
11483
|
+
try {
|
|
11484
|
+
const fs = await import("fs/promises");
|
|
11485
|
+
await fs.unlink(filepath);
|
|
10761
11486
|
return true;
|
|
11487
|
+
} catch {
|
|
11488
|
+
return false;
|
|
10762
11489
|
}
|
|
10763
|
-
|
|
10764
|
-
|
|
10765
|
-
|
|
10766
|
-
|
|
10767
|
-
|
|
10768
|
-
|
|
10769
|
-
|
|
10770
|
-
|
|
10771
|
-
|
|
10772
|
-
|
|
10773
|
-
|
|
10774
|
-
|
|
10775
|
-
|
|
10776
|
-
|
|
11490
|
+
}
|
|
11491
|
+
async function ensureDirectory(dirpath) {
|
|
11492
|
+
const fs = await import("fs/promises");
|
|
11493
|
+
await fs.mkdir(dirpath, { recursive: true });
|
|
11494
|
+
}
|
|
11495
|
+
function createFileWatcher(options) {
|
|
11496
|
+
const {
|
|
11497
|
+
dirpath,
|
|
11498
|
+
schema,
|
|
11499
|
+
contentColumn,
|
|
11500
|
+
debounceMs = WATCHER_DEBOUNCE_MS
|
|
11501
|
+
} = options;
|
|
11502
|
+
const _isWatching = signal(false);
|
|
11503
|
+
const _callbacks = new Set;
|
|
11504
|
+
const _savingIds = new Set;
|
|
11505
|
+
const _knownFiles = new Set;
|
|
11506
|
+
const _pendingChanges = new Map;
|
|
11507
|
+
let _watcher = null;
|
|
11508
|
+
async function processChange(filename) {
|
|
11509
|
+
if (!filename.endsWith(".md"))
|
|
11510
|
+
return;
|
|
11511
|
+
const id = filenameToId(filename);
|
|
11512
|
+
const filepath = `${dirpath}/${filename}`;
|
|
11513
|
+
if (_savingIds.has(id)) {
|
|
11514
|
+
return;
|
|
10777
11515
|
}
|
|
10778
|
-
|
|
10779
|
-
|
|
10780
|
-
|
|
10781
|
-
|
|
10782
|
-
|
|
10783
|
-
|
|
10784
|
-
|
|
10785
|
-
|
|
10786
|
-
|
|
10787
|
-
const withMeta = {
|
|
11516
|
+
const file = Bun.file(filepath);
|
|
11517
|
+
const exists = await file.exists();
|
|
11518
|
+
let event;
|
|
11519
|
+
if (!exists) {
|
|
11520
|
+
if (!_knownFiles.has(filename))
|
|
11521
|
+
return;
|
|
11522
|
+
_knownFiles.delete(filename);
|
|
11523
|
+
event = {
|
|
11524
|
+
type: "delete",
|
|
10788
11525
|
id,
|
|
10789
|
-
|
|
10790
|
-
|
|
10791
|
-
|
|
10792
|
-
stale: this._staleFlags[index] || false
|
|
11526
|
+
filename,
|
|
11527
|
+
filepath,
|
|
11528
|
+
stale: false
|
|
10793
11529
|
};
|
|
10794
|
-
|
|
10795
|
-
|
|
11530
|
+
} else {
|
|
11531
|
+
const isNew = !_knownFiles.has(filename);
|
|
11532
|
+
_knownFiles.add(filename);
|
|
11533
|
+
const result = await loadFromMarkdown(filepath, schema, contentColumn);
|
|
11534
|
+
if (!result)
|
|
11535
|
+
return;
|
|
11536
|
+
let stale = false;
|
|
11537
|
+
if (options.isStaleCallback && contentColumn) {
|
|
11538
|
+
const content = result.record[contentColumn];
|
|
11539
|
+
if (content) {
|
|
11540
|
+
stale = options.isStaleCallback(id, content);
|
|
11541
|
+
}
|
|
10796
11542
|
}
|
|
10797
|
-
|
|
10798
|
-
|
|
10799
|
-
}
|
|
10800
|
-
findOne(filter) {
|
|
10801
|
-
for (const index of getAllIndices()) {
|
|
10802
|
-
const id = getId(index);
|
|
10803
|
-
if (!id)
|
|
10804
|
-
continue;
|
|
10805
|
-
const record = this._columns.getRecord(index);
|
|
10806
|
-
const withMeta = {
|
|
11543
|
+
event = {
|
|
11544
|
+
type: isNew ? "create" : "update",
|
|
10807
11545
|
id,
|
|
10808
|
-
|
|
10809
|
-
|
|
10810
|
-
|
|
10811
|
-
stale
|
|
11546
|
+
filename,
|
|
11547
|
+
filepath,
|
|
11548
|
+
record: result.record,
|
|
11549
|
+
stale
|
|
10812
11550
|
};
|
|
10813
|
-
if (filter(withMeta)) {
|
|
10814
|
-
return withMeta;
|
|
10815
|
-
}
|
|
10816
|
-
}
|
|
10817
|
-
return null;
|
|
10818
|
-
}
|
|
10819
|
-
all() {
|
|
10820
|
-
return this.find(() => true);
|
|
10821
|
-
}
|
|
10822
|
-
count(filter) {
|
|
10823
|
-
if (!filter) {
|
|
10824
|
-
return registry.count;
|
|
10825
|
-
}
|
|
10826
|
-
return this.find(filter).length;
|
|
10827
|
-
}
|
|
10828
|
-
async insertMany(records) {
|
|
10829
|
-
const ids = [];
|
|
10830
|
-
for (const record of records) {
|
|
10831
|
-
const id = await this.insert(record);
|
|
10832
|
-
ids.push(id);
|
|
10833
11551
|
}
|
|
10834
|
-
|
|
10835
|
-
|
|
10836
|
-
|
|
10837
|
-
|
|
10838
|
-
|
|
10839
|
-
|
|
10840
|
-
const success = await this.update(record.id, data);
|
|
10841
|
-
if (success)
|
|
10842
|
-
count++;
|
|
10843
|
-
}
|
|
10844
|
-
return count;
|
|
10845
|
-
}
|
|
10846
|
-
async deleteMany(filter) {
|
|
10847
|
-
const matches = this.find(filter);
|
|
10848
|
-
let count = 0;
|
|
10849
|
-
for (const record of matches) {
|
|
10850
|
-
const success = await this.delete(record.id);
|
|
10851
|
-
if (success)
|
|
10852
|
-
count++;
|
|
11552
|
+
for (const callback of _callbacks) {
|
|
11553
|
+
try {
|
|
11554
|
+
await callback(event);
|
|
11555
|
+
} catch (err) {
|
|
11556
|
+
console.error("File watcher callback error:", err);
|
|
11557
|
+
}
|
|
10853
11558
|
}
|
|
10854
|
-
return count;
|
|
10855
11559
|
}
|
|
10856
|
-
|
|
10857
|
-
const
|
|
10858
|
-
|
|
10859
|
-
|
|
10860
|
-
let indices = getAllIndices();
|
|
10861
|
-
if (filter) {
|
|
10862
|
-
indices = indices.filter((idx) => {
|
|
10863
|
-
const id = getId(idx);
|
|
10864
|
-
if (!id)
|
|
10865
|
-
return false;
|
|
10866
|
-
const record = this._columns.getRecord(idx);
|
|
10867
|
-
return filter({ id, ...record });
|
|
10868
|
-
});
|
|
11560
|
+
function handleChange(filename) {
|
|
11561
|
+
const existing = _pendingChanges.get(filename);
|
|
11562
|
+
if (existing) {
|
|
11563
|
+
clearTimeout(existing);
|
|
10869
11564
|
}
|
|
10870
|
-
const
|
|
10871
|
-
|
|
10872
|
-
|
|
10873
|
-
|
|
10874
|
-
|
|
10875
|
-
return { id, ...record, similarity, stale };
|
|
10876
|
-
});
|
|
11565
|
+
const timeout = setTimeout(() => {
|
|
11566
|
+
_pendingChanges.delete(filename);
|
|
11567
|
+
processChange(filename);
|
|
11568
|
+
}, debounceMs);
|
|
11569
|
+
_pendingChanges.set(filename, timeout);
|
|
10877
11570
|
}
|
|
10878
|
-
|
|
10879
|
-
|
|
10880
|
-
|
|
10881
|
-
|
|
10882
|
-
|
|
10883
|
-
|
|
10884
|
-
|
|
10885
|
-
|
|
10886
|
-
continue;
|
|
10887
|
-
const index = allocateIndex(doc.id);
|
|
10888
|
-
for (const [key, value] of Object.entries(doc.frontmatter)) {
|
|
10889
|
-
if (key === "id")
|
|
10890
|
-
continue;
|
|
10891
|
-
if (key === "created") {
|
|
10892
|
-
this._created[index] = value;
|
|
10893
|
-
continue;
|
|
10894
|
-
}
|
|
10895
|
-
if (key === "updated") {
|
|
10896
|
-
this._updated[index] = value;
|
|
10897
|
-
continue;
|
|
11571
|
+
const watcher = {
|
|
11572
|
+
start() {
|
|
11573
|
+
if (_isWatching.value)
|
|
11574
|
+
return;
|
|
11575
|
+
try {
|
|
11576
|
+
const glob = new Bun.Glob("*.md");
|
|
11577
|
+
for (const filename of glob.scanSync({ cwd: dirpath })) {
|
|
11578
|
+
_knownFiles.add(filename);
|
|
10898
11579
|
}
|
|
10899
|
-
|
|
10900
|
-
|
|
10901
|
-
|
|
10902
|
-
this._columns.set(key, index, toFloat32Array(value));
|
|
11580
|
+
_watcher = import_fs.watch(dirpath, { recursive: false }, (eventType, filename) => {
|
|
11581
|
+
if (filename && filename.endsWith(".md")) {
|
|
11582
|
+
handleChange(filename);
|
|
10903
11583
|
}
|
|
10904
|
-
}
|
|
10905
|
-
|
|
10906
|
-
|
|
11584
|
+
});
|
|
11585
|
+
_isWatching.value = true;
|
|
11586
|
+
} catch (err) {
|
|
11587
|
+
console.error("Failed to start file watcher:", err);
|
|
10907
11588
|
}
|
|
10908
|
-
|
|
10909
|
-
|
|
11589
|
+
},
|
|
11590
|
+
stop() {
|
|
11591
|
+
if (!_isWatching.value)
|
|
11592
|
+
return;
|
|
11593
|
+
for (const timeout of _pendingChanges.values()) {
|
|
11594
|
+
clearTimeout(timeout);
|
|
10910
11595
|
}
|
|
10911
|
-
|
|
10912
|
-
|
|
10913
|
-
|
|
10914
|
-
|
|
10915
|
-
}
|
|
10916
|
-
return count;
|
|
10917
|
-
}
|
|
10918
|
-
_reconcileSchema() {
|
|
10919
|
-
const indices = getAllIndices();
|
|
10920
|
-
if (indices.length === 0)
|
|
10921
|
-
return;
|
|
10922
|
-
for (const [field, type] of Object.entries(this._options.schema)) {
|
|
10923
|
-
const column = this._columns.getColumn(field);
|
|
10924
|
-
const defaultValue = getDefaultForType(type);
|
|
10925
|
-
for (const index of indices) {
|
|
10926
|
-
if (column[index] === undefined) {
|
|
10927
|
-
this._columns.set(field, index, defaultValue);
|
|
10928
|
-
}
|
|
11596
|
+
_pendingChanges.clear();
|
|
11597
|
+
if (_watcher) {
|
|
11598
|
+
_watcher.close();
|
|
11599
|
+
_watcher = null;
|
|
10929
11600
|
}
|
|
11601
|
+
_isWatching.value = false;
|
|
11602
|
+
},
|
|
11603
|
+
get isWatching() {
|
|
11604
|
+
return _isWatching.value;
|
|
11605
|
+
},
|
|
11606
|
+
onChange(callback) {
|
|
11607
|
+
_callbacks.add(callback);
|
|
11608
|
+
return () => _callbacks.delete(callback);
|
|
11609
|
+
},
|
|
11610
|
+
markSaving(id) {
|
|
11611
|
+
_savingIds.add(id);
|
|
11612
|
+
},
|
|
11613
|
+
clearSaving(id) {
|
|
11614
|
+
setTimeout(() => {
|
|
11615
|
+
_savingIds.delete(id);
|
|
11616
|
+
}, SAVE_GRACE_PERIOD_MS);
|
|
10930
11617
|
}
|
|
11618
|
+
};
|
|
11619
|
+
return watcher;
|
|
11620
|
+
}
|
|
11621
|
+
function toFloat32Array(arr) {
|
|
11622
|
+
if (arr instanceof Float32Array)
|
|
11623
|
+
return arr;
|
|
11624
|
+
return new Float32Array(arr);
|
|
11625
|
+
}
|
|
11626
|
+
function cosineSimilarity(a, b) {
|
|
11627
|
+
const vecA = a instanceof Float32Array ? a : new Float32Array(a);
|
|
11628
|
+
const vecB = b instanceof Float32Array ? b : new Float32Array(b);
|
|
11629
|
+
if (vecA.length !== vecB.length) {
|
|
11630
|
+
throw new Error(`Vector dimension mismatch: ${vecA.length} vs ${vecB.length}`);
|
|
10931
11631
|
}
|
|
10932
|
-
|
|
10933
|
-
|
|
10934
|
-
|
|
10935
|
-
|
|
10936
|
-
|
|
10937
|
-
|
|
10938
|
-
|
|
10939
|
-
if (!id)
|
|
10940
|
-
continue;
|
|
10941
|
-
await this._saveRecord(id, index);
|
|
10942
|
-
count++;
|
|
10943
|
-
}
|
|
10944
|
-
return count;
|
|
10945
|
-
}
|
|
10946
|
-
get columns() {
|
|
10947
|
-
return this._columns;
|
|
10948
|
-
}
|
|
10949
|
-
get registry() {
|
|
10950
|
-
return registry;
|
|
10951
|
-
}
|
|
10952
|
-
getColumn(name) {
|
|
10953
|
-
return this._columns.getColumn(name);
|
|
10954
|
-
}
|
|
10955
|
-
createIndex(column) {
|
|
10956
|
-
return this._columns.createIndex(column);
|
|
10957
|
-
}
|
|
10958
|
-
getByIndex(index) {
|
|
10959
|
-
if (!registry.allocatedIndices.has(index))
|
|
10960
|
-
return null;
|
|
10961
|
-
return this._columns.getRecord(index);
|
|
11632
|
+
let dot = 0;
|
|
11633
|
+
let normA = 0;
|
|
11634
|
+
let normB = 0;
|
|
11635
|
+
for (let i = 0;i < vecA.length; i++) {
|
|
11636
|
+
dot += vecA[i] * vecB[i];
|
|
11637
|
+
normA += vecA[i] * vecA[i];
|
|
11638
|
+
normB += vecB[i] * vecB[i];
|
|
10962
11639
|
}
|
|
10963
|
-
|
|
10964
|
-
|
|
11640
|
+
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
11641
|
+
if (denom === 0)
|
|
11642
|
+
return 0;
|
|
11643
|
+
return dot / denom;
|
|
11644
|
+
}
|
|
11645
|
+
function batchCosineSimilarity(query, vectors, indices, topK) {
|
|
11646
|
+
let queryNorm = 0;
|
|
11647
|
+
for (let i = 0;i < query.length; i++) {
|
|
11648
|
+
queryNorm += query[i] * query[i];
|
|
10965
11649
|
}
|
|
10966
|
-
|
|
10967
|
-
|
|
11650
|
+
queryNorm = Math.sqrt(queryNorm);
|
|
11651
|
+
if (queryNorm === 0)
|
|
11652
|
+
return [];
|
|
11653
|
+
const results = [];
|
|
11654
|
+
for (let i = 0;i < vectors.length; i++) {
|
|
11655
|
+
const vec = vectors[i];
|
|
11656
|
+
if (!vec)
|
|
11657
|
+
continue;
|
|
11658
|
+
let dot = 0;
|
|
11659
|
+
let vecNorm = 0;
|
|
11660
|
+
for (let j = 0;j < query.length; j++) {
|
|
11661
|
+
dot += query[j] * vec[j];
|
|
11662
|
+
vecNorm += vec[j] * vec[j];
|
|
11663
|
+
}
|
|
11664
|
+
vecNorm = Math.sqrt(vecNorm);
|
|
11665
|
+
if (vecNorm === 0)
|
|
11666
|
+
continue;
|
|
11667
|
+
const similarity = dot / (queryNorm * vecNorm);
|
|
11668
|
+
results.push({ index: indices[i], similarity });
|
|
10968
11669
|
}
|
|
10969
|
-
|
|
10970
|
-
|
|
10971
|
-
|
|
10972
|
-
|
|
10973
|
-
|
|
10974
|
-
|
|
10975
|
-
|
|
10976
|
-
|
|
10977
|
-
|
|
10978
|
-
|
|
10979
|
-
|
|
10980
|
-
|
|
10981
|
-
|
|
10982
|
-
|
|
10983
|
-
|
|
10984
|
-
|
|
10985
|
-
|
|
10986
|
-
|
|
10987
|
-
|
|
10988
|
-
|
|
11670
|
+
results.sort((a, b) => b.similarity - a.similarity);
|
|
11671
|
+
return results.slice(0, topK);
|
|
11672
|
+
}
|
|
11673
|
+
function createEmbeddingManager() {
|
|
11674
|
+
const hashes = new ReactiveMap;
|
|
11675
|
+
return {
|
|
11676
|
+
setEmbedding(id, column, content) {
|
|
11677
|
+
const hash = BigInt(Bun.hash(content));
|
|
11678
|
+
let columnHashes = hashes.get(id);
|
|
11679
|
+
if (!columnHashes) {
|
|
11680
|
+
columnHashes = new Map;
|
|
11681
|
+
hashes.set(id, columnHashes);
|
|
11682
|
+
}
|
|
11683
|
+
columnHashes.set(column, hash);
|
|
11684
|
+
},
|
|
11685
|
+
isStale(id, column, currentContent) {
|
|
11686
|
+
const columnHashes = hashes.get(id);
|
|
11687
|
+
if (!columnHashes)
|
|
11688
|
+
return false;
|
|
11689
|
+
const storedHash = columnHashes.get(column);
|
|
11690
|
+
if (storedHash === undefined)
|
|
11691
|
+
return false;
|
|
11692
|
+
const currentHash = BigInt(Bun.hash(currentContent));
|
|
11693
|
+
return storedHash !== currentHash;
|
|
11694
|
+
},
|
|
11695
|
+
getHash(id, column) {
|
|
11696
|
+
return hashes.get(id)?.get(column);
|
|
11697
|
+
},
|
|
11698
|
+
clearHash(id, column) {
|
|
11699
|
+
const columnHashes = hashes.get(id);
|
|
11700
|
+
if (columnHashes) {
|
|
11701
|
+
columnHashes.delete(column);
|
|
11702
|
+
if (columnHashes.size === 0) {
|
|
11703
|
+
hashes.delete(id);
|
|
10989
11704
|
}
|
|
10990
11705
|
}
|
|
10991
|
-
|
|
10992
|
-
|
|
10993
|
-
|
|
10994
|
-
} finally {
|
|
10995
|
-
setTimeout(() => {
|
|
10996
|
-
this._isSaving.delete(id);
|
|
10997
|
-
}, 200);
|
|
10998
|
-
}
|
|
10999
|
-
}
|
|
11000
|
-
async startWatching() {
|
|
11001
|
-
if (!this._options.path) {
|
|
11002
|
-
throw new Error("No storage path configured");
|
|
11706
|
+
},
|
|
11707
|
+
reset() {
|
|
11708
|
+
hashes.clear();
|
|
11003
11709
|
}
|
|
11004
|
-
|
|
11005
|
-
|
|
11710
|
+
};
|
|
11711
|
+
}
|
|
11712
|
+
function vectorSearch(collection, vectorColumn, queryVector, options = {}) {
|
|
11713
|
+
const { topK = 10, minSimilarity = 0, filter } = options;
|
|
11714
|
+
const query = toFloat32Array(queryVector);
|
|
11715
|
+
const vectors = [];
|
|
11716
|
+
const vectorIndices = [];
|
|
11717
|
+
for (const index of collection.getIndices()) {
|
|
11718
|
+
if (filter) {
|
|
11719
|
+
const data = collection.columns.getRecord(index);
|
|
11720
|
+
if (!filter(data, index))
|
|
11721
|
+
continue;
|
|
11006
11722
|
}
|
|
11007
|
-
|
|
11008
|
-
|
|
11009
|
-
|
|
11010
|
-
|
|
11011
|
-
if (this._watcher) {
|
|
11012
|
-
this._watcher.stop();
|
|
11013
|
-
this._watcher = null;
|
|
11723
|
+
const vec = collection.columns.get(vectorColumn, index);
|
|
11724
|
+
if (vec) {
|
|
11725
|
+
vectors.push(vec);
|
|
11726
|
+
vectorIndices.push(index);
|
|
11014
11727
|
}
|
|
11015
11728
|
}
|
|
11016
|
-
|
|
11017
|
-
|
|
11729
|
+
const topResults = batchCosineSimilarity(query, vectors, vectorIndices, topK);
|
|
11730
|
+
const results = [];
|
|
11731
|
+
for (const { index, similarity } of topResults) {
|
|
11732
|
+
if (similarity < minSimilarity)
|
|
11733
|
+
continue;
|
|
11734
|
+
const record = collection.getByIndex(index);
|
|
11735
|
+
if (!record)
|
|
11736
|
+
continue;
|
|
11737
|
+
results.push({
|
|
11738
|
+
record,
|
|
11739
|
+
similarity,
|
|
11740
|
+
stale: collection.isStale(record.id)
|
|
11741
|
+
});
|
|
11018
11742
|
}
|
|
11019
|
-
|
|
11020
|
-
|
|
11021
|
-
|
|
11022
|
-
|
|
11743
|
+
return results;
|
|
11744
|
+
}
|
|
11745
|
+
function createPersistentCollection(name, options) {
|
|
11746
|
+
const baseCollection = createCollection(name, options);
|
|
11747
|
+
const { path, schema, contentColumn, autoSave = false, watchFiles = false, onExternalChange } = options;
|
|
11748
|
+
const embeddingManager = createEmbeddingManager();
|
|
11749
|
+
let fileWatcher = null;
|
|
11750
|
+
const savingIds = new Set;
|
|
11751
|
+
function getFilepath(id) {
|
|
11752
|
+
return `${path}/${idToFilename(id)}`;
|
|
11753
|
+
}
|
|
11754
|
+
async function saveRecord(id) {
|
|
11755
|
+
const record = baseCollection.get(id);
|
|
11756
|
+
if (!record)
|
|
11757
|
+
return false;
|
|
11758
|
+
savingIds.add(id);
|
|
11759
|
+
if (fileWatcher)
|
|
11760
|
+
fileWatcher.markSaving(id);
|
|
11761
|
+
const success = await saveToMarkdown(getFilepath(id), record, schema, contentColumn);
|
|
11762
|
+
setTimeout(() => {
|
|
11763
|
+
savingIds.delete(id);
|
|
11764
|
+
if (fileWatcher)
|
|
11765
|
+
fileWatcher.clearSaving(id);
|
|
11766
|
+
}, 200);
|
|
11767
|
+
return success;
|
|
11768
|
+
}
|
|
11769
|
+
async function deleteFile(id) {
|
|
11770
|
+
return await deleteMarkdownFile(getFilepath(id));
|
|
11771
|
+
}
|
|
11772
|
+
function isContentStale(id, content) {
|
|
11773
|
+
for (const col of baseCollection.columns.schema.vectorColumns) {
|
|
11774
|
+
if (embeddingManager.isStale(id, String(col), content)) {
|
|
11775
|
+
return true;
|
|
11776
|
+
}
|
|
11023
11777
|
}
|
|
11024
|
-
|
|
11025
|
-
|
|
11026
|
-
|
|
11027
|
-
|
|
11028
|
-
|
|
11029
|
-
|
|
11030
|
-
|
|
11031
|
-
|
|
11032
|
-
|
|
11033
|
-
|
|
11034
|
-
|
|
11035
|
-
|
|
11036
|
-
|
|
11037
|
-
|
|
11038
|
-
|
|
11039
|
-
|
|
11778
|
+
return false;
|
|
11779
|
+
}
|
|
11780
|
+
const persistentCollection = {
|
|
11781
|
+
name: baseCollection.name,
|
|
11782
|
+
schema: baseCollection.schema,
|
|
11783
|
+
contentColumn: baseCollection.contentColumn,
|
|
11784
|
+
registry: baseCollection.registry,
|
|
11785
|
+
columns: baseCollection.columns,
|
|
11786
|
+
reactiveCount: baseCollection.reactiveCount,
|
|
11787
|
+
insert(data) {
|
|
11788
|
+
const id = baseCollection.insert(data);
|
|
11789
|
+
if (autoSave)
|
|
11790
|
+
saveRecord(id);
|
|
11791
|
+
return id;
|
|
11792
|
+
},
|
|
11793
|
+
insertMany(records) {
|
|
11794
|
+
const ids = baseCollection.insertMany(records);
|
|
11795
|
+
if (autoSave) {
|
|
11796
|
+
for (const id of ids)
|
|
11797
|
+
saveRecord(id);
|
|
11798
|
+
}
|
|
11799
|
+
return ids;
|
|
11800
|
+
},
|
|
11801
|
+
get: baseCollection.get.bind(baseCollection),
|
|
11802
|
+
all: baseCollection.all.bind(baseCollection),
|
|
11803
|
+
find: baseCollection.find.bind(baseCollection),
|
|
11804
|
+
findOne: baseCollection.findOne.bind(baseCollection),
|
|
11805
|
+
update(id, data) {
|
|
11806
|
+
const success = baseCollection.update(id, data);
|
|
11807
|
+
if (success && autoSave)
|
|
11808
|
+
saveRecord(id);
|
|
11809
|
+
return success;
|
|
11810
|
+
},
|
|
11811
|
+
updateField(id, field, value) {
|
|
11812
|
+
const success = baseCollection.updateField(id, field, value);
|
|
11813
|
+
if (success && autoSave)
|
|
11814
|
+
saveRecord(id);
|
|
11815
|
+
return success;
|
|
11816
|
+
},
|
|
11817
|
+
updateMany(filter, data) {
|
|
11818
|
+
const count = baseCollection.updateMany(filter, data);
|
|
11819
|
+
if (count > 0 && autoSave) {
|
|
11820
|
+
const updated = baseCollection.find(filter);
|
|
11821
|
+
for (const record of updated)
|
|
11822
|
+
saveRecord(record.id);
|
|
11823
|
+
}
|
|
11824
|
+
return count;
|
|
11825
|
+
},
|
|
11826
|
+
delete(id) {
|
|
11827
|
+
const success = baseCollection.delete(id);
|
|
11828
|
+
if (success && autoSave)
|
|
11829
|
+
deleteFile(id);
|
|
11830
|
+
embeddingManager.clearHash(id, "*");
|
|
11831
|
+
return success;
|
|
11832
|
+
},
|
|
11833
|
+
deleteMany(filter) {
|
|
11834
|
+
const toDelete = baseCollection.find(filter).map((r) => r.id);
|
|
11835
|
+
const count = baseCollection.deleteMany(filter);
|
|
11836
|
+
if (autoSave) {
|
|
11837
|
+
for (const id of toDelete)
|
|
11838
|
+
deleteFile(id);
|
|
11839
|
+
}
|
|
11840
|
+
for (const id of toDelete) {
|
|
11841
|
+
embeddingManager.clearHash(id, "*");
|
|
11842
|
+
}
|
|
11843
|
+
return count;
|
|
11844
|
+
},
|
|
11845
|
+
count: baseCollection.count.bind(baseCollection),
|
|
11846
|
+
getByIndex: baseCollection.getByIndex.bind(baseCollection),
|
|
11847
|
+
getIndices: baseCollection.getIndices.bind(baseCollection),
|
|
11848
|
+
has: baseCollection.has.bind(baseCollection),
|
|
11849
|
+
isStale: baseCollection.isStale.bind(baseCollection),
|
|
11850
|
+
getStaleIds: baseCollection.getStaleIds.bind(baseCollection),
|
|
11851
|
+
setStale: baseCollection.setStale.bind(baseCollection),
|
|
11852
|
+
setMetadata: baseCollection.setMetadata.bind(baseCollection),
|
|
11853
|
+
clear() {
|
|
11854
|
+
baseCollection.clear();
|
|
11855
|
+
embeddingManager.reset();
|
|
11856
|
+
},
|
|
11857
|
+
async load() {
|
|
11858
|
+
await ensureDirectory(path);
|
|
11859
|
+
const loaded = await loadFromDirectory(path, schema, contentColumn);
|
|
11860
|
+
for (const { id, record } of loaded) {
|
|
11861
|
+
const index = baseCollection.registry.allocate(id);
|
|
11862
|
+
baseCollection.columns.setRecord(index, record);
|
|
11863
|
+
const created = record.created ?? Date.now();
|
|
11864
|
+
const updated = record.updated ?? created;
|
|
11865
|
+
const stale = record.stale ?? false;
|
|
11866
|
+
baseCollection.setMetadata(id, created, updated, stale);
|
|
11867
|
+
if (contentColumn) {
|
|
11868
|
+
const content = record[contentColumn];
|
|
11869
|
+
if (content && isContentStale(id, content)) {
|
|
11870
|
+
baseCollection.setStale(id, true);
|
|
11040
11871
|
}
|
|
11041
11872
|
}
|
|
11042
|
-
}
|
|
11043
|
-
|
|
11044
|
-
|
|
11873
|
+
}
|
|
11874
|
+
return loaded.length;
|
|
11875
|
+
},
|
|
11876
|
+
async save() {
|
|
11877
|
+
await ensureDirectory(path);
|
|
11878
|
+
const records = baseCollection.all();
|
|
11879
|
+
for (const record of records) {
|
|
11880
|
+
await saveRecord(record.id);
|
|
11881
|
+
}
|
|
11882
|
+
return records.length;
|
|
11883
|
+
},
|
|
11884
|
+
startWatching() {
|
|
11885
|
+
if (fileWatcher)
|
|
11886
|
+
return;
|
|
11887
|
+
fileWatcher = createFileWatcher({
|
|
11888
|
+
dirpath: path,
|
|
11889
|
+
schema,
|
|
11890
|
+
contentColumn,
|
|
11891
|
+
isStaleCallback: contentColumn ? (id, content) => isContentStale(id, content) : undefined
|
|
11892
|
+
});
|
|
11893
|
+
fileWatcher.onChange(async (event) => {
|
|
11894
|
+
if (savingIds.has(event.id))
|
|
11045
11895
|
return;
|
|
11046
|
-
|
|
11047
|
-
|
|
11048
|
-
if (
|
|
11049
|
-
const
|
|
11050
|
-
|
|
11051
|
-
|
|
11052
|
-
|
|
11053
|
-
|
|
11054
|
-
break;
|
|
11055
|
-
}
|
|
11056
|
-
}
|
|
11057
|
-
}
|
|
11058
|
-
this._staleFlags[index] = isStale;
|
|
11059
|
-
for (const [key, value] of Object.entries(doc.frontmatter)) {
|
|
11060
|
-
if (key === "id")
|
|
11061
|
-
continue;
|
|
11062
|
-
if (key === "created") {
|
|
11063
|
-
this._created[index] = value;
|
|
11064
|
-
continue;
|
|
11065
|
-
}
|
|
11066
|
-
if (key === "updated") {
|
|
11067
|
-
this._updated[index] = value;
|
|
11068
|
-
continue;
|
|
11896
|
+
if (event.type === "delete") {
|
|
11897
|
+
baseCollection.delete(event.id);
|
|
11898
|
+
} else if (event.record) {
|
|
11899
|
+
const exists = baseCollection.has(event.id);
|
|
11900
|
+
if (exists) {
|
|
11901
|
+
baseCollection.update(event.id, event.record);
|
|
11902
|
+
} else {
|
|
11903
|
+
baseCollection.insert({ ...event.record, id: event.id });
|
|
11069
11904
|
}
|
|
11070
|
-
|
|
11071
|
-
|
|
11072
|
-
if (Array.isArray(value)) {
|
|
11073
|
-
this._columns.set(key, index, toFloat32Array(value));
|
|
11074
|
-
}
|
|
11075
|
-
} else if (key in this._options.schema) {
|
|
11076
|
-
this._columns.set(key, index, value);
|
|
11905
|
+
if (event.stale) {
|
|
11906
|
+
baseCollection.setStale(event.id, true);
|
|
11077
11907
|
}
|
|
11078
11908
|
}
|
|
11079
|
-
if (
|
|
11080
|
-
|
|
11081
|
-
}
|
|
11082
|
-
if (this._onFileChange) {
|
|
11083
|
-
const record = this._columns.getRecord(index);
|
|
11084
|
-
this._onFileChange({ ...event, record, stale: isStale });
|
|
11909
|
+
if (onExternalChange) {
|
|
11910
|
+
await onExternalChange(event);
|
|
11085
11911
|
}
|
|
11912
|
+
});
|
|
11913
|
+
fileWatcher.start();
|
|
11914
|
+
},
|
|
11915
|
+
stopWatching() {
|
|
11916
|
+
if (fileWatcher) {
|
|
11917
|
+
fileWatcher.stop();
|
|
11918
|
+
fileWatcher = null;
|
|
11919
|
+
}
|
|
11920
|
+
},
|
|
11921
|
+
get isWatching() {
|
|
11922
|
+
return fileWatcher?.isWatching ?? false;
|
|
11923
|
+
},
|
|
11924
|
+
onFileChange(callback) {
|
|
11925
|
+
if (!fileWatcher) {
|
|
11926
|
+
persistentCollection.startWatching();
|
|
11086
11927
|
}
|
|
11087
|
-
|
|
11088
|
-
|
|
11928
|
+
return fileWatcher.onChange(callback);
|
|
11929
|
+
},
|
|
11930
|
+
setEmbedding(id, column, embedding, sourceContent) {
|
|
11931
|
+
const vec = embedding instanceof Float32Array ? embedding : new Float32Array(embedding);
|
|
11932
|
+
baseCollection.updateField(id, column, vec);
|
|
11933
|
+
embeddingManager.setEmbedding(id, String(column), sourceContent);
|
|
11934
|
+
baseCollection.setStale(id, false);
|
|
11935
|
+
if (autoSave)
|
|
11936
|
+
saveRecord(id);
|
|
11937
|
+
},
|
|
11938
|
+
search(column, queryVector, options2) {
|
|
11939
|
+
return vectorSearch(baseCollection, column, queryVector, options2);
|
|
11940
|
+
},
|
|
11941
|
+
close() {
|
|
11942
|
+
persistentCollection.stopWatching();
|
|
11943
|
+
baseCollection.clear();
|
|
11944
|
+
embeddingManager.reset();
|
|
11089
11945
|
}
|
|
11946
|
+
};
|
|
11947
|
+
if (watchFiles) {
|
|
11948
|
+
persistentCollection.startWatching();
|
|
11949
|
+
}
|
|
11950
|
+
return persistentCollection;
|
|
11951
|
+
}
|
|
11952
|
+
function createDatabase(options = {}) {
|
|
11953
|
+
const name = options.name ?? "default";
|
|
11954
|
+
let basePath;
|
|
11955
|
+
if (options.basePath) {
|
|
11956
|
+
basePath = options.basePath;
|
|
11957
|
+
} else if (options.local) {
|
|
11958
|
+
basePath = `${process.cwd()}/.fsdb/${name}`;
|
|
11959
|
+
} else {
|
|
11960
|
+
basePath = `${Bun.env.HOME}/.fsdb/${name}`;
|
|
11090
11961
|
}
|
|
11091
|
-
|
|
11092
|
-
|
|
11093
|
-
|
|
11094
|
-
|
|
11095
|
-
|
|
11096
|
-
|
|
11097
|
-
|
|
11098
|
-
|
|
11099
|
-
|
|
11100
|
-
const
|
|
11101
|
-
|
|
11102
|
-
|
|
11103
|
-
|
|
11104
|
-
|
|
11105
|
-
|
|
11962
|
+
const collections = new ReactiveMap;
|
|
11963
|
+
return {
|
|
11964
|
+
name,
|
|
11965
|
+
basePath,
|
|
11966
|
+
collection(collectionName, collectionOptions) {
|
|
11967
|
+
const existing = collections.get(collectionName);
|
|
11968
|
+
if (existing) {
|
|
11969
|
+
return existing;
|
|
11970
|
+
}
|
|
11971
|
+
const path = `${basePath}/${collectionName}`;
|
|
11972
|
+
const collection = createPersistentCollection(collectionName, {
|
|
11973
|
+
...collectionOptions,
|
|
11974
|
+
path
|
|
11975
|
+
});
|
|
11976
|
+
collections.set(collectionName, collection);
|
|
11977
|
+
return collection;
|
|
11978
|
+
},
|
|
11979
|
+
getCollection(collectionName) {
|
|
11980
|
+
return collections.get(collectionName);
|
|
11981
|
+
},
|
|
11982
|
+
listCollections() {
|
|
11983
|
+
return Array.from(collections.keys());
|
|
11984
|
+
},
|
|
11985
|
+
close() {
|
|
11986
|
+
for (const collection of collections.values()) {
|
|
11987
|
+
collection.close();
|
|
11988
|
+
}
|
|
11989
|
+
collections.clear();
|
|
11106
11990
|
}
|
|
11107
|
-
}
|
|
11108
|
-
return db;
|
|
11991
|
+
};
|
|
11109
11992
|
}
|
|
11110
11993
|
|
|
11111
11994
|
// src/core/store.ts
|
|
11112
11995
|
var import_os = require("os");
|
|
11113
|
-
var
|
|
11996
|
+
var import_path = require("path");
|
|
11114
11997
|
|
|
11115
11998
|
// src/types/schema.ts
|
|
11116
11999
|
var memorySchema = {
|
|
@@ -11159,7 +12042,7 @@ class MemoryStore {
|
|
|
11159
12042
|
_projects = new Map;
|
|
11160
12043
|
constructor(config = {}) {
|
|
11161
12044
|
this._config = {
|
|
11162
|
-
basePath: config.basePath ??
|
|
12045
|
+
basePath: config.basePath ?? import_path.join(import_os.homedir(), ".local", "share", "memory"),
|
|
11163
12046
|
watchFiles: config.watchFiles ?? false
|
|
11164
12047
|
};
|
|
11165
12048
|
}
|
|
@@ -11169,43 +12052,47 @@ class MemoryStore {
|
|
|
11169
12052
|
return this._projects.get(projectId);
|
|
11170
12053
|
}
|
|
11171
12054
|
console.log(`\uD83C\uDD95 [DEBUG] Creating NEW databases for ${projectId}`);
|
|
11172
|
-
const projectPath =
|
|
12055
|
+
const projectPath = import_path.join(this._config.basePath, projectId);
|
|
11173
12056
|
console.log(` Path: ${projectPath}`);
|
|
11174
|
-
const
|
|
11175
|
-
|
|
11176
|
-
|
|
11177
|
-
|
|
11178
|
-
|
|
11179
|
-
|
|
11180
|
-
|
|
11181
|
-
|
|
11182
|
-
|
|
11183
|
-
|
|
11184
|
-
|
|
11185
|
-
|
|
11186
|
-
|
|
11187
|
-
|
|
11188
|
-
|
|
11189
|
-
|
|
11190
|
-
|
|
11191
|
-
|
|
11192
|
-
|
|
11193
|
-
|
|
11194
|
-
|
|
11195
|
-
|
|
11196
|
-
|
|
11197
|
-
|
|
11198
|
-
|
|
11199
|
-
|
|
11200
|
-
|
|
12057
|
+
const db = createDatabase({
|
|
12058
|
+
name: projectId,
|
|
12059
|
+
basePath: projectPath
|
|
12060
|
+
});
|
|
12061
|
+
const memories = db.collection("memories", {
|
|
12062
|
+
schema: memorySchema,
|
|
12063
|
+
contentColumn: "content",
|
|
12064
|
+
autoSave: true,
|
|
12065
|
+
watchFiles: this._config.watchFiles
|
|
12066
|
+
});
|
|
12067
|
+
const summaries = db.collection("summaries", {
|
|
12068
|
+
schema: sessionSummarySchema,
|
|
12069
|
+
contentColumn: "summary",
|
|
12070
|
+
autoSave: true,
|
|
12071
|
+
watchFiles: this._config.watchFiles
|
|
12072
|
+
});
|
|
12073
|
+
const snapshots = db.collection("snapshots", {
|
|
12074
|
+
schema: projectSnapshotSchema,
|
|
12075
|
+
autoSave: true,
|
|
12076
|
+
watchFiles: this._config.watchFiles
|
|
12077
|
+
});
|
|
12078
|
+
const sessions = db.collection("sessions", {
|
|
12079
|
+
schema: sessionSchema,
|
|
12080
|
+
autoSave: true,
|
|
12081
|
+
watchFiles: this._config.watchFiles
|
|
12082
|
+
});
|
|
12083
|
+
await Promise.all([
|
|
12084
|
+
memories.load(),
|
|
12085
|
+
summaries.load(),
|
|
12086
|
+
snapshots.load(),
|
|
12087
|
+
sessions.load()
|
|
11201
12088
|
]);
|
|
11202
|
-
const
|
|
11203
|
-
this._projects.set(projectId,
|
|
11204
|
-
return
|
|
12089
|
+
const projectDB = { db, memories, summaries, snapshots, sessions };
|
|
12090
|
+
this._projects.set(projectId, projectDB);
|
|
12091
|
+
return projectDB;
|
|
11205
12092
|
}
|
|
11206
12093
|
async storeMemory(projectId, sessionId, memory, embedding) {
|
|
11207
12094
|
const { memories } = await this.getProject(projectId);
|
|
11208
|
-
const id =
|
|
12095
|
+
const id = memories.insert({
|
|
11209
12096
|
content: memory.content,
|
|
11210
12097
|
reasoning: memory.reasoning,
|
|
11211
12098
|
importance_weight: memory.importance_weight,
|
|
@@ -11221,7 +12108,7 @@ class MemoryStore {
|
|
|
11221
12108
|
question_types: memory.question_types,
|
|
11222
12109
|
session_id: sessionId,
|
|
11223
12110
|
project_id: projectId,
|
|
11224
|
-
embedding: embedding ? embedding instanceof Float32Array ? embedding : new Float32Array(embedding) :
|
|
12111
|
+
embedding: embedding ? embedding instanceof Float32Array ? embedding : new Float32Array(embedding) : null
|
|
11225
12112
|
});
|
|
11226
12113
|
return id;
|
|
11227
12114
|
}
|
|
@@ -11244,7 +12131,7 @@ class MemoryStore {
|
|
|
11244
12131
|
question_types: record.question_types,
|
|
11245
12132
|
session_id: record.session_id,
|
|
11246
12133
|
project_id: record.project_id,
|
|
11247
|
-
embedding: record.embedding,
|
|
12134
|
+
embedding: record.embedding ?? undefined,
|
|
11248
12135
|
created_at: record.created,
|
|
11249
12136
|
updated_at: record.updated,
|
|
11250
12137
|
stale: record.stale
|
|
@@ -11255,9 +12142,9 @@ class MemoryStore {
|
|
|
11255
12142
|
const { topK = 10, filter } = options;
|
|
11256
12143
|
const results = memories.search("embedding", queryEmbedding, {
|
|
11257
12144
|
topK,
|
|
11258
|
-
filter: filter ? (record) => {
|
|
12145
|
+
filter: filter ? (record, _idx) => {
|
|
11259
12146
|
const mem = {
|
|
11260
|
-
id:
|
|
12147
|
+
id: "",
|
|
11261
12148
|
content: record.content,
|
|
11262
12149
|
reasoning: record.reasoning,
|
|
11263
12150
|
importance_weight: record.importance_weight,
|
|
@@ -11279,36 +12166,37 @@ class MemoryStore {
|
|
|
11279
12166
|
return filter(mem);
|
|
11280
12167
|
} : undefined
|
|
11281
12168
|
});
|
|
11282
|
-
return results.map((
|
|
11283
|
-
id: record.id,
|
|
11284
|
-
content: record.content,
|
|
11285
|
-
reasoning: record.reasoning,
|
|
11286
|
-
importance_weight: record.importance_weight,
|
|
11287
|
-
confidence_score: record.confidence_score,
|
|
11288
|
-
context_type: record.context_type,
|
|
11289
|
-
temporal_relevance: record.temporal_relevance,
|
|
11290
|
-
knowledge_domain: record.knowledge_domain,
|
|
11291
|
-
emotional_resonance: record.emotional_resonance,
|
|
11292
|
-
action_required: record.action_required,
|
|
11293
|
-
problem_solution_pair: record.problem_solution_pair,
|
|
11294
|
-
semantic_tags: record.semantic_tags,
|
|
11295
|
-
trigger_phrases: record.trigger_phrases,
|
|
11296
|
-
question_types: record.question_types,
|
|
11297
|
-
session_id: record.session_id,
|
|
11298
|
-
project_id: record.project_id,
|
|
11299
|
-
embedding: record.embedding,
|
|
11300
|
-
created_at: record.created,
|
|
11301
|
-
updated_at: record.updated,
|
|
11302
|
-
stale:
|
|
12169
|
+
return results.map((result) => ({
|
|
12170
|
+
id: result.record.id,
|
|
12171
|
+
content: result.record.content,
|
|
12172
|
+
reasoning: result.record.reasoning,
|
|
12173
|
+
importance_weight: result.record.importance_weight,
|
|
12174
|
+
confidence_score: result.record.confidence_score,
|
|
12175
|
+
context_type: result.record.context_type,
|
|
12176
|
+
temporal_relevance: result.record.temporal_relevance,
|
|
12177
|
+
knowledge_domain: result.record.knowledge_domain,
|
|
12178
|
+
emotional_resonance: result.record.emotional_resonance,
|
|
12179
|
+
action_required: result.record.action_required,
|
|
12180
|
+
problem_solution_pair: result.record.problem_solution_pair,
|
|
12181
|
+
semantic_tags: result.record.semantic_tags,
|
|
12182
|
+
trigger_phrases: result.record.trigger_phrases,
|
|
12183
|
+
question_types: result.record.question_types,
|
|
12184
|
+
session_id: result.record.session_id,
|
|
12185
|
+
project_id: result.record.project_id,
|
|
12186
|
+
embedding: result.record.embedding ?? undefined,
|
|
12187
|
+
created_at: result.record.created,
|
|
12188
|
+
updated_at: result.record.updated,
|
|
12189
|
+
stale: result.stale
|
|
11303
12190
|
}));
|
|
11304
12191
|
}
|
|
11305
12192
|
async setMemoryEmbedding(projectId, memoryId, embedding, content) {
|
|
11306
12193
|
const { memories } = await this.getProject(projectId);
|
|
11307
|
-
|
|
12194
|
+
const vec = embedding instanceof Float32Array ? embedding : new Float32Array(embedding);
|
|
12195
|
+
memories.setEmbedding(memoryId, "embedding", vec, content);
|
|
11308
12196
|
}
|
|
11309
12197
|
async getStaleMemoryIds(projectId) {
|
|
11310
12198
|
const { memories } = await this.getProject(projectId);
|
|
11311
|
-
return memories.
|
|
12199
|
+
return memories.all().filter((r) => r.stale).map((r) => r.id);
|
|
11312
12200
|
}
|
|
11313
12201
|
async getOrCreateSession(projectId, sessionId) {
|
|
11314
12202
|
const { sessions } = await this.getProject(projectId);
|
|
@@ -11322,7 +12210,7 @@ class MemoryStore {
|
|
|
11322
12210
|
}
|
|
11323
12211
|
const allSessions = sessions.all();
|
|
11324
12212
|
const firstSessionCompleted = allSessions.some((s) => s.first_session_completed);
|
|
11325
|
-
|
|
12213
|
+
sessions.insert({
|
|
11326
12214
|
id: sessionId,
|
|
11327
12215
|
project_id: projectId,
|
|
11328
12216
|
message_count: 0,
|
|
@@ -11343,7 +12231,7 @@ class MemoryStore {
|
|
|
11343
12231
|
throw new Error(`Session ${sessionId} not found`);
|
|
11344
12232
|
}
|
|
11345
12233
|
const newCount = session.message_count + 1;
|
|
11346
|
-
|
|
12234
|
+
sessions.update(sessionId, {
|
|
11347
12235
|
message_count: newCount,
|
|
11348
12236
|
last_active: Date.now()
|
|
11349
12237
|
});
|
|
@@ -11351,14 +12239,14 @@ class MemoryStore {
|
|
|
11351
12239
|
}
|
|
11352
12240
|
async markFirstSessionCompleted(projectId, sessionId) {
|
|
11353
12241
|
const { sessions } = await this.getProject(projectId);
|
|
11354
|
-
|
|
12242
|
+
sessions.update(sessionId, { first_session_completed: true });
|
|
11355
12243
|
}
|
|
11356
12244
|
async storeSessionSummary(projectId, sessionId, summary, interactionTone = "") {
|
|
11357
12245
|
const { summaries } = await this.getProject(projectId);
|
|
11358
12246
|
console.log(`\uD83D\uDCDD [DEBUG] Storing summary for ${projectId}:`);
|
|
11359
12247
|
console.log(` Summary length: ${summary.length} chars`);
|
|
11360
12248
|
console.log(` Summaries count before: ${summaries.all().length}`);
|
|
11361
|
-
const id =
|
|
12249
|
+
const id = summaries.insert({
|
|
11362
12250
|
session_id: sessionId,
|
|
11363
12251
|
project_id: projectId,
|
|
11364
12252
|
summary,
|
|
@@ -11377,8 +12265,8 @@ class MemoryStore {
|
|
|
11377
12265
|
console.log(` No summaries found!`);
|
|
11378
12266
|
return null;
|
|
11379
12267
|
}
|
|
11380
|
-
all.sort((a, b) => b.created - a.created);
|
|
11381
|
-
const latest =
|
|
12268
|
+
const sorted = [...all].sort((a, b) => b.created - a.created);
|
|
12269
|
+
const latest = sorted[0];
|
|
11382
12270
|
console.log(` Latest summary: ${latest.summary.slice(0, 50)}...`);
|
|
11383
12271
|
return {
|
|
11384
12272
|
id: latest.id,
|
|
@@ -11405,8 +12293,8 @@ class MemoryStore {
|
|
|
11405
12293
|
const all = snapshots.all();
|
|
11406
12294
|
if (!all.length)
|
|
11407
12295
|
return null;
|
|
11408
|
-
all.sort((a, b) => b.created - a.created);
|
|
11409
|
-
const latest =
|
|
12296
|
+
const sorted = [...all].sort((a, b) => b.created - a.created);
|
|
12297
|
+
const latest = sorted[0];
|
|
11410
12298
|
return {
|
|
11411
12299
|
id: latest.id,
|
|
11412
12300
|
session_id: latest.session_id,
|
|
@@ -11422,25 +12310,22 @@ class MemoryStore {
|
|
|
11422
12310
|
const { memories, sessions } = await this.getProject(projectId);
|
|
11423
12311
|
const allMemories = memories.all();
|
|
11424
12312
|
const allSessions = sessions.all();
|
|
11425
|
-
const
|
|
12313
|
+
const staleCount = allMemories.filter((r) => r.stale).length;
|
|
11426
12314
|
let latestSession = null;
|
|
11427
12315
|
if (allSessions.length) {
|
|
11428
|
-
allSessions.sort((a, b) => b.last_active - a.last_active);
|
|
11429
|
-
latestSession =
|
|
12316
|
+
const sorted = [...allSessions].sort((a, b) => b.last_active - a.last_active);
|
|
12317
|
+
latestSession = sorted[0].id;
|
|
11430
12318
|
}
|
|
11431
12319
|
return {
|
|
11432
12320
|
totalMemories: allMemories.length,
|
|
11433
12321
|
totalSessions: allSessions.length,
|
|
11434
|
-
staleMemories:
|
|
12322
|
+
staleMemories: staleCount,
|
|
11435
12323
|
latestSession
|
|
11436
12324
|
};
|
|
11437
12325
|
}
|
|
11438
12326
|
close() {
|
|
11439
|
-
for (const
|
|
11440
|
-
|
|
11441
|
-
dbs.summaries.close();
|
|
11442
|
-
dbs.snapshots.close();
|
|
11443
|
-
dbs.sessions.close();
|
|
12327
|
+
for (const projectDB of this._projects.values()) {
|
|
12328
|
+
projectDB.db.close();
|
|
11444
12329
|
}
|
|
11445
12330
|
this._projects.clear();
|
|
11446
12331
|
}
|
|
@@ -11449,9 +12334,205 @@ function createStore(config) {
|
|
|
11449
12334
|
return new MemoryStore(config);
|
|
11450
12335
|
}
|
|
11451
12336
|
|
|
12337
|
+
// src/utils/logger.ts
|
|
12338
|
+
var import_util = require("util");
|
|
12339
|
+
var style = (format, text) => import_util.styleText(format, text);
|
|
12340
|
+
function timestamp() {
|
|
12341
|
+
return style("dim", new Date().toISOString().slice(11, 19));
|
|
12342
|
+
}
|
|
12343
|
+
function shortId(id) {
|
|
12344
|
+
return style("dim", id.slice(0, 8) + "...");
|
|
12345
|
+
}
|
|
12346
|
+
var sym = {
|
|
12347
|
+
brain: "\uD83E\uDDE0",
|
|
12348
|
+
sparkles: "✨",
|
|
12349
|
+
book: "\uD83D\uDCD6",
|
|
12350
|
+
calendar: "\uD83D\uDCC5",
|
|
12351
|
+
arrow: "→",
|
|
12352
|
+
check: "✓",
|
|
12353
|
+
cross: "✗",
|
|
12354
|
+
warning: "⚠",
|
|
12355
|
+
info: "ℹ",
|
|
12356
|
+
bullet: "•",
|
|
12357
|
+
fire: "\uD83D\uDD25",
|
|
12358
|
+
target: "\uD83C\uDFAF"
|
|
12359
|
+
};
|
|
12360
|
+
var logger = {
|
|
12361
|
+
info(message) {
|
|
12362
|
+
console.log(`${timestamp()} ${style("cyan", sym.info)} ${message}`);
|
|
12363
|
+
},
|
|
12364
|
+
success(message) {
|
|
12365
|
+
console.log(`${timestamp()} ${style("green", sym.check)} ${message}`);
|
|
12366
|
+
},
|
|
12367
|
+
warn(message) {
|
|
12368
|
+
console.log(`${timestamp()} ${style("yellow", sym.warning)} ${message}`);
|
|
12369
|
+
},
|
|
12370
|
+
error(message) {
|
|
12371
|
+
console.error(`${timestamp()} ${style("red", sym.cross)} ${message}`);
|
|
12372
|
+
},
|
|
12373
|
+
memory(message) {
|
|
12374
|
+
console.log(`${timestamp()} ${style("magenta", sym.brain)} ${message}`);
|
|
12375
|
+
},
|
|
12376
|
+
inject(message) {
|
|
12377
|
+
console.log(`${timestamp()} ${style("cyan", sym.sparkles)} ${message}`);
|
|
12378
|
+
},
|
|
12379
|
+
session(message) {
|
|
12380
|
+
console.log(`${timestamp()} ${style("blue", sym.calendar)} ${message}`);
|
|
12381
|
+
},
|
|
12382
|
+
primer(message) {
|
|
12383
|
+
console.log(`${timestamp()} ${style("yellow", sym.book)} ${message}`);
|
|
12384
|
+
},
|
|
12385
|
+
divider() {
|
|
12386
|
+
console.log(style("dim", "─".repeat(60)));
|
|
12387
|
+
},
|
|
12388
|
+
request(method, path, projectId) {
|
|
12389
|
+
const proj = projectId ? style("dim", ` [${projectId}]`) : "";
|
|
12390
|
+
console.log(`${timestamp()} ${style("dim", sym.arrow)} ${style("cyan", method)} ${path}${proj}`);
|
|
12391
|
+
},
|
|
12392
|
+
logCuratedMemories(memories) {
|
|
12393
|
+
console.log();
|
|
12394
|
+
console.log(`${timestamp()} ${style("magenta", sym.brain)} ${style(["bold", "magenta"], `CURATED ${memories.length} MEMORIES`)}`);
|
|
12395
|
+
console.log();
|
|
12396
|
+
memories.forEach((m, i) => {
|
|
12397
|
+
const importance = style("yellow", `${(m.importance_weight * 100).toFixed(0)}%`);
|
|
12398
|
+
const type = style("cyan", m.context_type.toUpperCase());
|
|
12399
|
+
const num = style("dim", `${i + 1}.`);
|
|
12400
|
+
console.log(` ${num} [${type}] ${importance}`);
|
|
12401
|
+
const preview = m.content.length > 70 ? m.content.slice(0, 70) + style("dim", "...") : m.content;
|
|
12402
|
+
console.log(` ${style("white", preview)}`);
|
|
12403
|
+
if (m.semantic_tags?.length) {
|
|
12404
|
+
const tags = m.semantic_tags.slice(0, 4).join(style("dim", ", "));
|
|
12405
|
+
console.log(` ${style("dim", "tags:")} ${tags}`);
|
|
12406
|
+
}
|
|
12407
|
+
if (m.action_required) {
|
|
12408
|
+
console.log(` ${style("red", "⚡ ACTION REQUIRED")}`);
|
|
12409
|
+
}
|
|
12410
|
+
console.log();
|
|
12411
|
+
});
|
|
12412
|
+
},
|
|
12413
|
+
logRetrievedMemories(memories, query) {
|
|
12414
|
+
const queryPreview = query.length > 40 ? query.slice(0, 40) + "..." : query;
|
|
12415
|
+
const emojiMap = {
|
|
12416
|
+
breakthrough: "\uD83D\uDCA1",
|
|
12417
|
+
decision: "⚖️",
|
|
12418
|
+
personal: "\uD83D\uDC9C",
|
|
12419
|
+
technical: "\uD83D\uDD27",
|
|
12420
|
+
technical_state: "\uD83D\uDCCD",
|
|
12421
|
+
unresolved: "❓",
|
|
12422
|
+
preference: "⚙️",
|
|
12423
|
+
workflow: "\uD83D\uDD04",
|
|
12424
|
+
architectural: "\uD83C\uDFD7️",
|
|
12425
|
+
debugging: "\uD83D\uDC1B",
|
|
12426
|
+
philosophy: "\uD83C\uDF00",
|
|
12427
|
+
todo: "\uD83C\uDFAF",
|
|
12428
|
+
implementation: "⚡",
|
|
12429
|
+
problem_solution: "✅",
|
|
12430
|
+
project_context: "\uD83D\uDCE6",
|
|
12431
|
+
milestone: "\uD83C\uDFC6",
|
|
12432
|
+
general: "\uD83D\uDCDD"
|
|
12433
|
+
};
|
|
12434
|
+
console.log();
|
|
12435
|
+
console.log(`${timestamp()} ${style("cyan", sym.sparkles)} ${style("bold", `SURFACING ${memories.length} MEMORIES`)}`);
|
|
12436
|
+
console.log(` ${style("dim", "query:")} "${queryPreview}"`);
|
|
12437
|
+
console.log();
|
|
12438
|
+
if (memories.length === 0) {
|
|
12439
|
+
console.log(` ${style("dim", "(no relevant memories for this context)")}`);
|
|
12440
|
+
console.log();
|
|
12441
|
+
return;
|
|
12442
|
+
}
|
|
12443
|
+
memories.forEach((m, i) => {
|
|
12444
|
+
const score = style("green", `${(m.score * 100).toFixed(0)}%`);
|
|
12445
|
+
const emoji = emojiMap[m.context_type?.toLowerCase()] ?? "\uD83D\uDCDD";
|
|
12446
|
+
const num = style("dim", `${i + 1}.`);
|
|
12447
|
+
const preview = m.content.length > 55 ? m.content.slice(0, 55) + style("dim", "...") : m.content;
|
|
12448
|
+
console.log(` ${num} [${score}] ${emoji}`);
|
|
12449
|
+
console.log(` ${preview}`);
|
|
12450
|
+
});
|
|
12451
|
+
console.log();
|
|
12452
|
+
},
|
|
12453
|
+
startup(port, host, mode) {
|
|
12454
|
+
console.log();
|
|
12455
|
+
console.log(style(["bold", "magenta"], "┌──────────────────────────────────────────────────────────┐"));
|
|
12456
|
+
console.log(style(["bold", "magenta"], "│") + style("bold", ` ${sym.brain} MEMORY SERVER `) + style(["bold", "magenta"], "│"));
|
|
12457
|
+
console.log(style(["bold", "magenta"], "└──────────────────────────────────────────────────────────┘"));
|
|
12458
|
+
console.log();
|
|
12459
|
+
console.log(` ${style("dim", "url:")} ${style("cyan", `http://${host}:${port}`)}`);
|
|
12460
|
+
console.log(` ${style("dim", "storage:")} ${mode}`);
|
|
12461
|
+
console.log(` ${style("dim", "engine:")} TypeScript + fsdb`);
|
|
12462
|
+
console.log();
|
|
12463
|
+
this.divider();
|
|
12464
|
+
console.log();
|
|
12465
|
+
},
|
|
12466
|
+
logSessionStart(sessionId, projectId, isNew) {
|
|
12467
|
+
const status = isNew ? style("green", "new session") : style("blue", "continuing");
|
|
12468
|
+
console.log();
|
|
12469
|
+
console.log(`${timestamp()} ${style("blue", sym.calendar)} ${style("bold", "SESSION")} ${shortId(sessionId)}`);
|
|
12470
|
+
console.log(` ${style("dim", "project:")} ${projectId}`);
|
|
12471
|
+
console.log(` ${style("dim", "status:")} ${status}`);
|
|
12472
|
+
console.log();
|
|
12473
|
+
},
|
|
12474
|
+
logCurationStart(sessionId, trigger) {
|
|
12475
|
+
console.log();
|
|
12476
|
+
console.log(`${timestamp()} ${style("magenta", sym.brain)} ${style("bold", "CURATING")} ${shortId(sessionId)}`);
|
|
12477
|
+
console.log(` ${style("dim", "trigger:")} ${trigger}`);
|
|
12478
|
+
},
|
|
12479
|
+
logCurationComplete(memoriesCount, summary) {
|
|
12480
|
+
if (memoriesCount > 0) {
|
|
12481
|
+
console.log(` ${style("dim", "memories:")} ${style("green", String(memoriesCount))} extracted`);
|
|
12482
|
+
if (summary) {
|
|
12483
|
+
const shortSummary = summary.length > 50 ? summary.slice(0, 50) + "..." : summary;
|
|
12484
|
+
console.log(` ${style("dim", "summary:")} ${shortSummary}`);
|
|
12485
|
+
}
|
|
12486
|
+
} else {
|
|
12487
|
+
console.log(` ${style("dim", "result:")} no memories to extract`);
|
|
12488
|
+
}
|
|
12489
|
+
console.log();
|
|
12490
|
+
},
|
|
12491
|
+
logRetrievalScoring(params) {
|
|
12492
|
+
const { totalMemories, currentMessage, alreadyInjected, mustIncludeCount, remainingSlots, finalCount, selectedMemories } = params;
|
|
12493
|
+
console.log();
|
|
12494
|
+
console.log(`${timestamp()} ${style("magenta", sym.brain)} ${style("bold", "TWO-STAGE MEMORY FILTERING")}`);
|
|
12495
|
+
console.log(` ${style("dim", "candidates:")} ${totalMemories} memories`);
|
|
12496
|
+
console.log(` ${style("dim", "already injected:")} ${alreadyInjected}`);
|
|
12497
|
+
const msgPreview = currentMessage.length > 60 ? currentMessage.slice(0, 60) + "..." : currentMessage;
|
|
12498
|
+
console.log(` ${style("dim", "trigger:")} "${msgPreview}"`);
|
|
12499
|
+
console.log();
|
|
12500
|
+
console.log(` ${style("cyan", "Stage 1:")} ${mustIncludeCount} must-include (critical/action-required)`);
|
|
12501
|
+
console.log(` ${style("cyan", "Stage 2:")} ${remainingSlots} slots for scored selection`);
|
|
12502
|
+
console.log(` ${style("green", "Final:")} ${finalCount} memories selected`);
|
|
12503
|
+
console.log();
|
|
12504
|
+
if (selectedMemories.length === 0) {
|
|
12505
|
+
console.log(` ${style("dim", "\uD83D\uDCED No relevant memories for this context")}`);
|
|
12506
|
+
console.log();
|
|
12507
|
+
return;
|
|
12508
|
+
}
|
|
12509
|
+
console.log(style("dim", " ─".repeat(30)));
|
|
12510
|
+
console.log(` ${style("bold", "SELECTION DETAILS")}`);
|
|
12511
|
+
console.log();
|
|
12512
|
+
selectedMemories.forEach((m, i) => {
|
|
12513
|
+
const num = style("dim", `${i + 1}.`);
|
|
12514
|
+
const score = style("green", `${(m.score * 100).toFixed(0)}%`);
|
|
12515
|
+
const relevance = style("cyan", `rel:${(m.relevance_score * 100).toFixed(0)}%`);
|
|
12516
|
+
const type = style("yellow", m.context_type.toUpperCase());
|
|
12517
|
+
console.log(` ${num} [${score} ${relevance}] ${type}`);
|
|
12518
|
+
const preview = m.content.length > 60 ? m.content.slice(0, 60) + style("dim", "...") : m.content;
|
|
12519
|
+
console.log(` ${style("white", preview)}`);
|
|
12520
|
+
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(", ");
|
|
12521
|
+
if (components) {
|
|
12522
|
+
console.log(` ${style("dim", "scores:")} ${components}`);
|
|
12523
|
+
}
|
|
12524
|
+
if (m.semantic_tags?.length) {
|
|
12525
|
+
const tags = m.semantic_tags.slice(0, 3).join(", ");
|
|
12526
|
+
console.log(` ${style("dim", "tags:")} ${tags}`);
|
|
12527
|
+
}
|
|
12528
|
+
console.log();
|
|
12529
|
+
});
|
|
12530
|
+
}
|
|
12531
|
+
};
|
|
12532
|
+
|
|
11452
12533
|
// src/core/retrieval.ts
|
|
11453
12534
|
class SmartVectorRetrieval {
|
|
11454
|
-
retrieveRelevantMemories(allMemories, currentMessage, queryEmbedding, sessionContext, maxMemories = 5) {
|
|
12535
|
+
retrieveRelevantMemories(allMemories, currentMessage, queryEmbedding, sessionContext, maxMemories = 5, alreadyInjectedCount = 0) {
|
|
11455
12536
|
if (!allMemories.length) {
|
|
11456
12537
|
return [];
|
|
11457
12538
|
}
|
|
@@ -11550,6 +12631,24 @@ class SmartVectorRetrieval {
|
|
|
11550
12631
|
}
|
|
11551
12632
|
}
|
|
11552
12633
|
const finalSelected = selected.slice(0, maxMemories);
|
|
12634
|
+
logger.logRetrievalScoring({
|
|
12635
|
+
totalMemories: allMemories.length,
|
|
12636
|
+
currentMessage,
|
|
12637
|
+
alreadyInjected: alreadyInjectedCount,
|
|
12638
|
+
mustIncludeCount: mustInclude.length,
|
|
12639
|
+
remainingSlots,
|
|
12640
|
+
finalCount: finalSelected.length,
|
|
12641
|
+
selectedMemories: finalSelected.map((item) => ({
|
|
12642
|
+
content: item.memory.content,
|
|
12643
|
+
reasoning: item.reasoning,
|
|
12644
|
+
score: item.score,
|
|
12645
|
+
relevance_score: item.relevance_score,
|
|
12646
|
+
importance_weight: item.memory.importance_weight ?? 0.5,
|
|
12647
|
+
context_type: item.memory.context_type ?? "general",
|
|
12648
|
+
semantic_tags: item.memory.semantic_tags ?? [],
|
|
12649
|
+
components: item.components
|
|
12650
|
+
}))
|
|
12651
|
+
});
|
|
11553
12652
|
return finalSelected.map((item) => ({
|
|
11554
12653
|
...item.memory,
|
|
11555
12654
|
score: item.score,
|
|
@@ -11747,35 +12846,65 @@ function createRetrieval() {
|
|
|
11747
12846
|
return new SmartVectorRetrieval;
|
|
11748
12847
|
}
|
|
11749
12848
|
|
|
12849
|
+
// src/types/memory.ts
|
|
12850
|
+
var MEMORY_TYPE_EMOJI = {
|
|
12851
|
+
breakthrough: "\uD83D\uDCA1",
|
|
12852
|
+
decision: "⚖️",
|
|
12853
|
+
personal: "\uD83D\uDC9C",
|
|
12854
|
+
technical: "\uD83D\uDD27",
|
|
12855
|
+
technical_state: "\uD83D\uDCCD",
|
|
12856
|
+
unresolved: "❓",
|
|
12857
|
+
preference: "⚙️",
|
|
12858
|
+
workflow: "\uD83D\uDD04",
|
|
12859
|
+
architectural: "\uD83C\uDFD7️",
|
|
12860
|
+
debugging: "\uD83D\uDC1B",
|
|
12861
|
+
philosophy: "\uD83C\uDF00",
|
|
12862
|
+
todo: "\uD83C\uDFAF",
|
|
12863
|
+
implementation: "⚡",
|
|
12864
|
+
problem_solution: "✅",
|
|
12865
|
+
project_context: "\uD83D\uDCE6",
|
|
12866
|
+
milestone: "\uD83C\uDFC6",
|
|
12867
|
+
general: "\uD83D\uDCDD"
|
|
12868
|
+
};
|
|
12869
|
+
function getMemoryEmoji(contextType) {
|
|
12870
|
+
return MEMORY_TYPE_EMOJI[contextType.toLowerCase()] ?? "\uD83D\uDCDD";
|
|
12871
|
+
}
|
|
12872
|
+
|
|
11750
12873
|
// src/core/engine.ts
|
|
11751
12874
|
class MemoryEngine {
|
|
11752
12875
|
_config;
|
|
11753
12876
|
_stores = new Map;
|
|
11754
12877
|
_retrieval;
|
|
12878
|
+
_sessionMetadata = new Map;
|
|
11755
12879
|
constructor(config = {}) {
|
|
11756
12880
|
this._config = {
|
|
11757
12881
|
storageMode: config.storageMode ?? "central",
|
|
11758
|
-
centralPath: config.centralPath ??
|
|
12882
|
+
centralPath: config.centralPath ?? import_path2.join(import_os2.homedir(), ".local", "share", "memory"),
|
|
11759
12883
|
localFolder: config.localFolder ?? ".memory",
|
|
11760
12884
|
maxMemories: config.maxMemories ?? 5,
|
|
11761
12885
|
embedder: config.embedder
|
|
11762
12886
|
};
|
|
11763
12887
|
this._retrieval = createRetrieval();
|
|
11764
12888
|
}
|
|
12889
|
+
_getSessionMetadata(sessionId, projectId) {
|
|
12890
|
+
if (!this._sessionMetadata.has(sessionId)) {
|
|
12891
|
+
this._sessionMetadata.set(sessionId, {
|
|
12892
|
+
message_count: 0,
|
|
12893
|
+
started_at: Date.now(),
|
|
12894
|
+
project_id: projectId,
|
|
12895
|
+
injected_memories: new Set
|
|
12896
|
+
});
|
|
12897
|
+
}
|
|
12898
|
+
return this._sessionMetadata.get(sessionId);
|
|
12899
|
+
}
|
|
11765
12900
|
async _getStore(projectId, projectPath) {
|
|
11766
12901
|
const key = this._config.storageMode === "local" && projectPath ? projectPath : projectId;
|
|
11767
|
-
console.log(`\uD83C\uDFEA [DEBUG] _getStore called:`);
|
|
11768
|
-
console.log(` projectId: ${projectId}`);
|
|
11769
|
-
console.log(` projectPath: ${projectPath}`);
|
|
11770
|
-
console.log(` storageMode: ${this._config.storageMode}`);
|
|
11771
|
-
console.log(` cache key: ${key}`);
|
|
11772
|
-
console.log(` cached: ${this._stores.has(key)}`);
|
|
11773
12902
|
if (this._stores.has(key)) {
|
|
11774
12903
|
return this._stores.get(key);
|
|
11775
12904
|
}
|
|
11776
12905
|
let basePath;
|
|
11777
12906
|
if (this._config.storageMode === "local" && projectPath) {
|
|
11778
|
-
basePath =
|
|
12907
|
+
basePath = import_path2.join(projectPath, this._config.localFolder);
|
|
11779
12908
|
} else {
|
|
11780
12909
|
basePath = this._config.centralPath;
|
|
11781
12910
|
}
|
|
@@ -11804,10 +12933,16 @@ class MemoryEngine {
|
|
|
11804
12933
|
if (!currentMessage.trim()) {
|
|
11805
12934
|
return { memories: [], formatted: "" };
|
|
11806
12935
|
}
|
|
12936
|
+
const sessionMeta = this._getSessionMetadata(sessionId, projectId);
|
|
12937
|
+
const injectedIds = sessionMeta.injected_memories;
|
|
11807
12938
|
const allMemories = await store.getAllMemories(projectId);
|
|
11808
12939
|
if (!allMemories.length) {
|
|
11809
12940
|
return { memories: [], formatted: "" };
|
|
11810
12941
|
}
|
|
12942
|
+
const candidateMemories = allMemories.filter((m) => !injectedIds.has(m.id));
|
|
12943
|
+
if (!candidateMemories.length) {
|
|
12944
|
+
return { memories: [], formatted: "" };
|
|
12945
|
+
}
|
|
11811
12946
|
let queryEmbedding;
|
|
11812
12947
|
if (this._config.embedder) {
|
|
11813
12948
|
queryEmbedding = await this._config.embedder(currentMessage);
|
|
@@ -11817,7 +12952,10 @@ class MemoryEngine {
|
|
|
11817
12952
|
project_id: projectId,
|
|
11818
12953
|
message_count: messageCount
|
|
11819
12954
|
};
|
|
11820
|
-
const relevantMemories = this._retrieval.retrieveRelevantMemories(
|
|
12955
|
+
const relevantMemories = this._retrieval.retrieveRelevantMemories(candidateMemories, currentMessage, queryEmbedding ?? new Float32Array(384), sessionContext, maxMemories, injectedIds.size);
|
|
12956
|
+
for (const memory of relevantMemories) {
|
|
12957
|
+
injectedIds.add(memory.id);
|
|
12958
|
+
}
|
|
11821
12959
|
return {
|
|
11822
12960
|
memories: relevantMemories,
|
|
11823
12961
|
formatted: this._formatMemories(relevantMemories)
|
|
@@ -11862,12 +13000,32 @@ class MemoryEngine {
|
|
|
11862
13000
|
const timeSince = Date.now() - summary.created_at;
|
|
11863
13001
|
temporalContext = this._formatTimeSince(timeSince);
|
|
11864
13002
|
}
|
|
13003
|
+
const currentDatetime = this._formatCurrentDatetime();
|
|
13004
|
+
const sessionNumber = stats.totalSessions + 1;
|
|
11865
13005
|
return {
|
|
11866
13006
|
temporal_context: temporalContext,
|
|
13007
|
+
current_datetime: currentDatetime,
|
|
13008
|
+
session_number: sessionNumber,
|
|
11867
13009
|
session_summary: summary?.summary,
|
|
11868
13010
|
project_status: snapshot ? this._formatSnapshot(snapshot) : undefined
|
|
11869
13011
|
};
|
|
11870
13012
|
}
|
|
13013
|
+
_formatCurrentDatetime() {
|
|
13014
|
+
const now = new Date;
|
|
13015
|
+
const dayOfWeek = now.toLocaleDateString("en-US", { weekday: "long" });
|
|
13016
|
+
const fullDate = now.toLocaleDateString("en-US", {
|
|
13017
|
+
month: "long",
|
|
13018
|
+
day: "numeric",
|
|
13019
|
+
year: "numeric"
|
|
13020
|
+
});
|
|
13021
|
+
const time = now.toLocaleTimeString("en-US", {
|
|
13022
|
+
hour: "numeric",
|
|
13023
|
+
minute: "2-digit",
|
|
13024
|
+
hour12: true
|
|
13025
|
+
});
|
|
13026
|
+
const timezone = now.toLocaleTimeString("en-US", { timeZoneName: "short" }).split(" ").pop();
|
|
13027
|
+
return `${dayOfWeek}, ${fullDate} • ${time} • ${timezone}`;
|
|
13028
|
+
}
|
|
11871
13029
|
_formatTimeSince(ms) {
|
|
11872
13030
|
const minutes = Math.floor(ms / 60000);
|
|
11873
13031
|
const hours = Math.floor(minutes / 60);
|
|
@@ -11900,9 +13058,8 @@ class MemoryEngine {
|
|
|
11900
13058
|
}
|
|
11901
13059
|
_formatPrimer(primer) {
|
|
11902
13060
|
const parts = ["# Continuing Session"];
|
|
11903
|
-
|
|
11904
|
-
|
|
11905
|
-
}
|
|
13061
|
+
parts.push(`*Session #${primer.session_number}${primer.temporal_context ? ` • ${primer.temporal_context}` : ""}*`);
|
|
13062
|
+
parts.push(`\uD83D\uDCC5 ${primer.current_datetime}`);
|
|
11906
13063
|
if (primer.session_summary) {
|
|
11907
13064
|
parts.push(`
|
|
11908
13065
|
**Previous session**: ${primer.session_summary}`);
|
|
@@ -11912,6 +13069,8 @@ class MemoryEngine {
|
|
|
11912
13069
|
**Project status**: ${primer.project_status}`);
|
|
11913
13070
|
}
|
|
11914
13071
|
parts.push(`
|
|
13072
|
+
**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`);
|
|
13073
|
+
parts.push(`
|
|
11915
13074
|
*Memories will surface naturally as we converse.*`);
|
|
11916
13075
|
return parts.join(`
|
|
11917
13076
|
`);
|
|
@@ -11925,8 +13084,8 @@ class MemoryEngine {
|
|
|
11925
13084
|
for (const memory of memories) {
|
|
11926
13085
|
const tags = memory.semantic_tags?.join(", ") || "";
|
|
11927
13086
|
const importance = memory.importance_weight?.toFixed(1) || "0.5";
|
|
11928
|
-
const
|
|
11929
|
-
parts.push(`[${
|
|
13087
|
+
const emoji = getMemoryEmoji(memory.context_type || "general");
|
|
13088
|
+
parts.push(`[${emoji} • ${importance}] [${tags}] ${memory.content}`);
|
|
11930
13089
|
}
|
|
11931
13090
|
return parts.join(`
|
|
11932
13091
|
`);
|
|
@@ -11943,14 +13102,14 @@ function createEngine(config) {
|
|
|
11943
13102
|
}
|
|
11944
13103
|
// src/core/curator.ts
|
|
11945
13104
|
var import_os3 = require("os");
|
|
11946
|
-
var
|
|
13105
|
+
var import_path4 = require("path");
|
|
11947
13106
|
var import_fs3 = require("fs");
|
|
11948
13107
|
function getClaudeCommand() {
|
|
11949
13108
|
const envCommand = process.env.CURATOR_COMMAND;
|
|
11950
13109
|
if (envCommand) {
|
|
11951
13110
|
return envCommand;
|
|
11952
13111
|
}
|
|
11953
|
-
const claudeLocal =
|
|
13112
|
+
const claudeLocal = import_path4.join(import_os3.homedir(), ".claude", "local", "claude");
|
|
11954
13113
|
if (import_fs3.existsSync(claudeLocal)) {
|
|
11955
13114
|
return claudeLocal;
|
|
11956
13115
|
}
|
|
@@ -11966,7 +13125,6 @@ class Curator {
|
|
|
11966
13125
|
cliCommand,
|
|
11967
13126
|
cliType: config.cliType ?? "claude-code"
|
|
11968
13127
|
};
|
|
11969
|
-
console.log(`\uD83E\uDDE0 Curator initialized with CLI: ${cliCommand}`);
|
|
11970
13128
|
}
|
|
11971
13129
|
buildCurationPrompt(triggerType = "session_end") {
|
|
11972
13130
|
return `You have just had a conversation. As this session is ending (${triggerType}), please curate memories for the Claude Tools Memory System.
|
|
@@ -12044,8 +13202,9 @@ Return ONLY this JSON structure:
|
|
|
12044
13202
|
"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)",
|
|
12045
13203
|
"project_snapshot": {
|
|
12046
13204
|
"current_phase": "Current state (if applicable)",
|
|
12047
|
-
"recent_achievements": "What was accomplished (if applicable)",
|
|
12048
|
-
"active_challenges": "What remains (if applicable)"
|
|
13205
|
+
"recent_achievements": ["What was accomplished (if applicable)"],
|
|
13206
|
+
"active_challenges": ["What remains (if applicable)"],
|
|
13207
|
+
"next_steps": ["Planned next actions (if applicable)"]
|
|
12049
13208
|
},
|
|
12050
13209
|
"memories": [
|
|
12051
13210
|
{
|
|
@@ -12088,8 +13247,7 @@ Return ONLY this JSON structure:
|
|
|
12088
13247
|
} : undefined,
|
|
12089
13248
|
memories: this._parseMemories(data.memories ?? [])
|
|
12090
13249
|
};
|
|
12091
|
-
} catch
|
|
12092
|
-
console.error("Failed to parse curation response:", error);
|
|
13250
|
+
} catch {
|
|
12093
13251
|
return {
|
|
12094
13252
|
session_summary: "",
|
|
12095
13253
|
memories: []
|
|
@@ -12159,25 +13317,21 @@ ${prompt}`
|
|
|
12159
13317
|
}
|
|
12160
13318
|
return this.parseCurationResponse(content.text);
|
|
12161
13319
|
}
|
|
12162
|
-
async curateWithCLI(sessionId, triggerType = "session_end", cwd) {
|
|
13320
|
+
async curateWithCLI(sessionId, triggerType = "session_end", cwd, cliTypeOverride) {
|
|
13321
|
+
const type = cliTypeOverride ?? this._config.cliType;
|
|
12163
13322
|
const systemPrompt = this.buildCurationPrompt(triggerType);
|
|
12164
13323
|
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.";
|
|
12165
13324
|
const args = [];
|
|
12166
|
-
|
|
13325
|
+
let command = this._config.cliCommand;
|
|
13326
|
+
if (type === "claude-code") {
|
|
12167
13327
|
args.push("--resume", sessionId, "-p", userMessage, "--append-system-prompt", systemPrompt, "--output-format", "json", "--max-turns", "1");
|
|
12168
13328
|
} else {
|
|
13329
|
+
command = "gemini";
|
|
12169
13330
|
args.push("--resume", sessionId, "-p", `${systemPrompt}
|
|
12170
13331
|
|
|
12171
13332
|
${userMessage}`, "--output-format", "json");
|
|
12172
13333
|
}
|
|
12173
|
-
|
|
12174
|
-
\uD83D\uDCCB Executing CLI command:`);
|
|
12175
|
-
console.log(` Command: ${this._config.cliCommand}`);
|
|
12176
|
-
console.log(` Args: --resume ${sessionId} -p [user_message] --append-system-prompt [curation_instructions] --output-format json --max-turns 1`);
|
|
12177
|
-
console.log(` CWD: ${cwd || "not set"}`);
|
|
12178
|
-
console.log(` User message: "${userMessage.slice(0, 50)}..."`);
|
|
12179
|
-
console.log(` System prompt length: ${systemPrompt.length} chars`);
|
|
12180
|
-
const proc = Bun.spawn([this._config.cliCommand, ...args], {
|
|
13334
|
+
const proc = Bun.spawn([command, ...args], {
|
|
12181
13335
|
cwd,
|
|
12182
13336
|
env: {
|
|
12183
13337
|
...process.env,
|
|
@@ -12190,67 +13344,29 @@ ${userMessage}`, "--output-format", "json");
|
|
|
12190
13344
|
new Response(proc.stderr).text()
|
|
12191
13345
|
]);
|
|
12192
13346
|
const exitCode = await proc.exited;
|
|
12193
|
-
console.log(`
|
|
12194
|
-
\uD83D\uDCE4 CLI Response:`);
|
|
12195
|
-
console.log(` Exit code: ${exitCode}`);
|
|
12196
|
-
console.log(` Stdout length: ${stdout.length} chars`);
|
|
12197
|
-
console.log(` Stderr length: ${stderr.length} chars`);
|
|
12198
|
-
if (stderr) {
|
|
12199
|
-
console.log(`
|
|
12200
|
-
⚠️ Stderr output:`);
|
|
12201
|
-
console.log(stderr.slice(0, 1000));
|
|
12202
|
-
}
|
|
12203
|
-
if (stdout) {
|
|
12204
|
-
console.log(`
|
|
12205
|
-
\uD83D\uDCE5 Stdout output (first 500 chars):`);
|
|
12206
|
-
console.log(stdout.slice(0, 500));
|
|
12207
|
-
}
|
|
12208
13347
|
if (exitCode !== 0) {
|
|
12209
|
-
console.error(`
|
|
12210
|
-
❌ CLI exited with code ${exitCode}`);
|
|
12211
13348
|
return { session_summary: "", memories: [] };
|
|
12212
13349
|
}
|
|
12213
13350
|
try {
|
|
12214
13351
|
const cliOutput = JSON.parse(stdout);
|
|
12215
13352
|
if (cliOutput.type === "error" || cliOutput.is_error === true) {
|
|
12216
|
-
console.log(`
|
|
12217
|
-
❌ CLI returned error:`);
|
|
12218
|
-
console.log(` Type: ${cliOutput.type}`);
|
|
12219
|
-
console.log(` Message: ${cliOutput.message || cliOutput.error || "Unknown error"}`);
|
|
12220
13353
|
return { session_summary: "", memories: [] };
|
|
12221
13354
|
}
|
|
12222
13355
|
let aiResponse = "";
|
|
12223
13356
|
if (typeof cliOutput.result === "string") {
|
|
12224
13357
|
aiResponse = cliOutput.result;
|
|
12225
|
-
console.log(`
|
|
12226
|
-
\uD83D\uDCE6 Extracted result from CLI wrapper (${aiResponse.length} chars)`);
|
|
12227
13358
|
} else {
|
|
12228
|
-
console.log(`
|
|
12229
|
-
⚠️ No result field in CLI output`);
|
|
12230
|
-
console.log(` Keys: ${Object.keys(cliOutput).join(", ")}`);
|
|
12231
13359
|
return { session_summary: "", memories: [] };
|
|
12232
13360
|
}
|
|
12233
13361
|
const codeBlockMatch = aiResponse.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
12234
13362
|
if (codeBlockMatch) {
|
|
12235
13363
|
aiResponse = codeBlockMatch[1].trim();
|
|
12236
|
-
console.log(`\uD83D\uDCDD Extracted JSON from markdown code block`);
|
|
12237
13364
|
}
|
|
12238
13365
|
const jsonMatch = aiResponse.match(/\{[\s\S]*\}/)?.[0];
|
|
12239
13366
|
if (jsonMatch) {
|
|
12240
|
-
|
|
12241
|
-
const result = this.parseCurationResponse(jsonMatch);
|
|
12242
|
-
console.log(` Parsed ${result.memories.length} memories`);
|
|
12243
|
-
return result;
|
|
12244
|
-
} else {
|
|
12245
|
-
console.log(`
|
|
12246
|
-
⚠️ No JSON object found in AI response`);
|
|
12247
|
-
console.log(` Response preview: ${aiResponse.slice(0, 200)}...`);
|
|
13367
|
+
return this.parseCurationResponse(jsonMatch);
|
|
12248
13368
|
}
|
|
12249
|
-
} catch
|
|
12250
|
-
console.error(`
|
|
12251
|
-
❌ Failed to parse CLI output:`, error);
|
|
12252
|
-
console.log(` Raw stdout (first 500 chars): ${stdout.slice(0, 500)}`);
|
|
12253
|
-
}
|
|
13369
|
+
} catch {}
|
|
12254
13370
|
return { session_summary: "", memories: [] };
|
|
12255
13371
|
}
|
|
12256
13372
|
}
|