@rlabs-inc/memory 0.3.2 → 0.3.5

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