@plur-ai/core 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -6,9 +6,787 @@ import {
|
|
|
6
6
|
ftsTokenize,
|
|
7
7
|
getSyncStatus,
|
|
8
8
|
searchEngrams,
|
|
9
|
-
sync
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
sync,
|
|
10
|
+
withLock
|
|
11
|
+
} from "./chunk-KMVQYBNP.js";
|
|
12
|
+
import {
|
|
13
|
+
__commonJS,
|
|
14
|
+
__require
|
|
15
|
+
} from "./chunk-2ZDO52B4.js";
|
|
16
|
+
|
|
17
|
+
// ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/util.js
|
|
18
|
+
var require_util = __commonJS({
|
|
19
|
+
"../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/util.js"(exports) {
|
|
20
|
+
"use strict";
|
|
21
|
+
exports.getBooleanOption = (options, key) => {
|
|
22
|
+
let value = false;
|
|
23
|
+
if (key in options && typeof (value = options[key]) !== "boolean") {
|
|
24
|
+
throw new TypeError(`Expected the "${key}" option to be a boolean`);
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
};
|
|
28
|
+
exports.cppdb = /* @__PURE__ */ Symbol();
|
|
29
|
+
exports.inspect = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/sqlite-error.js
|
|
34
|
+
var require_sqlite_error = __commonJS({
|
|
35
|
+
"../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/sqlite-error.js"(exports, module) {
|
|
36
|
+
"use strict";
|
|
37
|
+
var descriptor = { value: "SqliteError", writable: true, enumerable: false, configurable: true };
|
|
38
|
+
function SqliteError(message, code) {
|
|
39
|
+
if (new.target !== SqliteError) {
|
|
40
|
+
return new SqliteError(message, code);
|
|
41
|
+
}
|
|
42
|
+
if (typeof code !== "string") {
|
|
43
|
+
throw new TypeError("Expected second argument to be a string");
|
|
44
|
+
}
|
|
45
|
+
Error.call(this, message);
|
|
46
|
+
descriptor.value = "" + message;
|
|
47
|
+
Object.defineProperty(this, "message", descriptor);
|
|
48
|
+
Error.captureStackTrace(this, SqliteError);
|
|
49
|
+
this.code = code;
|
|
50
|
+
}
|
|
51
|
+
Object.setPrototypeOf(SqliteError, Error);
|
|
52
|
+
Object.setPrototypeOf(SqliteError.prototype, Error.prototype);
|
|
53
|
+
Object.defineProperty(SqliteError.prototype, "name", descriptor);
|
|
54
|
+
module.exports = SqliteError;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// ../../node_modules/.pnpm/file-uri-to-path@1.0.0/node_modules/file-uri-to-path/index.js
|
|
59
|
+
var require_file_uri_to_path = __commonJS({
|
|
60
|
+
"../../node_modules/.pnpm/file-uri-to-path@1.0.0/node_modules/file-uri-to-path/index.js"(exports, module) {
|
|
61
|
+
"use strict";
|
|
62
|
+
var sep = __require("path").sep || "/";
|
|
63
|
+
module.exports = fileUriToPath;
|
|
64
|
+
function fileUriToPath(uri) {
|
|
65
|
+
if ("string" != typeof uri || uri.length <= 7 || "file://" != uri.substring(0, 7)) {
|
|
66
|
+
throw new TypeError("must pass in a file:// URI to convert to a file path");
|
|
67
|
+
}
|
|
68
|
+
var rest = decodeURI(uri.substring(7));
|
|
69
|
+
var firstSlash = rest.indexOf("/");
|
|
70
|
+
var host = rest.substring(0, firstSlash);
|
|
71
|
+
var path2 = rest.substring(firstSlash + 1);
|
|
72
|
+
if ("localhost" == host) host = "";
|
|
73
|
+
if (host) {
|
|
74
|
+
host = sep + sep + host;
|
|
75
|
+
}
|
|
76
|
+
path2 = path2.replace(/^(.+)\|/, "$1:");
|
|
77
|
+
if (sep == "\\") {
|
|
78
|
+
path2 = path2.replace(/\//g, "\\");
|
|
79
|
+
}
|
|
80
|
+
if (/^.+\:/.test(path2)) {
|
|
81
|
+
} else {
|
|
82
|
+
path2 = sep + path2;
|
|
83
|
+
}
|
|
84
|
+
return host + path2;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// ../../node_modules/.pnpm/bindings@1.5.0/node_modules/bindings/bindings.js
|
|
90
|
+
var require_bindings = __commonJS({
|
|
91
|
+
"../../node_modules/.pnpm/bindings@1.5.0/node_modules/bindings/bindings.js"(exports, module) {
|
|
92
|
+
"use strict";
|
|
93
|
+
var fs3 = __require("fs");
|
|
94
|
+
var path2 = __require("path");
|
|
95
|
+
var fileURLToPath = require_file_uri_to_path();
|
|
96
|
+
var join3 = path2.join;
|
|
97
|
+
var dirname = path2.dirname;
|
|
98
|
+
var exists = fs3.accessSync && function(path3) {
|
|
99
|
+
try {
|
|
100
|
+
fs3.accessSync(path3);
|
|
101
|
+
} catch (e) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
return true;
|
|
105
|
+
} || fs3.existsSync || path2.existsSync;
|
|
106
|
+
var defaults = {
|
|
107
|
+
arrow: process.env.NODE_BINDINGS_ARROW || " \u2192 ",
|
|
108
|
+
compiled: process.env.NODE_BINDINGS_COMPILED_DIR || "compiled",
|
|
109
|
+
platform: process.platform,
|
|
110
|
+
arch: process.arch,
|
|
111
|
+
nodePreGyp: "node-v" + process.versions.modules + "-" + process.platform + "-" + process.arch,
|
|
112
|
+
version: process.versions.node,
|
|
113
|
+
bindings: "bindings.node",
|
|
114
|
+
try: [
|
|
115
|
+
// node-gyp's linked version in the "build" dir
|
|
116
|
+
["module_root", "build", "bindings"],
|
|
117
|
+
// node-waf and gyp_addon (a.k.a node-gyp)
|
|
118
|
+
["module_root", "build", "Debug", "bindings"],
|
|
119
|
+
["module_root", "build", "Release", "bindings"],
|
|
120
|
+
// Debug files, for development (legacy behavior, remove for node v0.9)
|
|
121
|
+
["module_root", "out", "Debug", "bindings"],
|
|
122
|
+
["module_root", "Debug", "bindings"],
|
|
123
|
+
// Release files, but manually compiled (legacy behavior, remove for node v0.9)
|
|
124
|
+
["module_root", "out", "Release", "bindings"],
|
|
125
|
+
["module_root", "Release", "bindings"],
|
|
126
|
+
// Legacy from node-waf, node <= 0.4.x
|
|
127
|
+
["module_root", "build", "default", "bindings"],
|
|
128
|
+
// Production "Release" buildtype binary (meh...)
|
|
129
|
+
["module_root", "compiled", "version", "platform", "arch", "bindings"],
|
|
130
|
+
// node-qbs builds
|
|
131
|
+
["module_root", "addon-build", "release", "install-root", "bindings"],
|
|
132
|
+
["module_root", "addon-build", "debug", "install-root", "bindings"],
|
|
133
|
+
["module_root", "addon-build", "default", "install-root", "bindings"],
|
|
134
|
+
// node-pre-gyp path ./lib/binding/{node_abi}-{platform}-{arch}
|
|
135
|
+
["module_root", "lib", "binding", "nodePreGyp", "bindings"]
|
|
136
|
+
]
|
|
137
|
+
};
|
|
138
|
+
function bindings(opts) {
|
|
139
|
+
if (typeof opts == "string") {
|
|
140
|
+
opts = { bindings: opts };
|
|
141
|
+
} else if (!opts) {
|
|
142
|
+
opts = {};
|
|
143
|
+
}
|
|
144
|
+
Object.keys(defaults).map(function(i2) {
|
|
145
|
+
if (!(i2 in opts)) opts[i2] = defaults[i2];
|
|
146
|
+
});
|
|
147
|
+
if (!opts.module_root) {
|
|
148
|
+
opts.module_root = exports.getRoot(exports.getFileName());
|
|
149
|
+
}
|
|
150
|
+
if (path2.extname(opts.bindings) != ".node") {
|
|
151
|
+
opts.bindings += ".node";
|
|
152
|
+
}
|
|
153
|
+
var requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
154
|
+
var tries = [], i = 0, l = opts.try.length, n, b, err;
|
|
155
|
+
for (; i < l; i++) {
|
|
156
|
+
n = join3.apply(
|
|
157
|
+
null,
|
|
158
|
+
opts.try[i].map(function(p) {
|
|
159
|
+
return opts[p] || p;
|
|
160
|
+
})
|
|
161
|
+
);
|
|
162
|
+
tries.push(n);
|
|
163
|
+
try {
|
|
164
|
+
b = opts.path ? requireFunc.resolve(n) : requireFunc(n);
|
|
165
|
+
if (!opts.path) {
|
|
166
|
+
b.path = n;
|
|
167
|
+
}
|
|
168
|
+
return b;
|
|
169
|
+
} catch (e) {
|
|
170
|
+
if (e.code !== "MODULE_NOT_FOUND" && e.code !== "QUALIFIED_PATH_RESOLUTION_FAILED" && !/not find/i.test(e.message)) {
|
|
171
|
+
throw e;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
err = new Error(
|
|
176
|
+
"Could not locate the bindings file. Tried:\n" + tries.map(function(a) {
|
|
177
|
+
return opts.arrow + a;
|
|
178
|
+
}).join("\n")
|
|
179
|
+
);
|
|
180
|
+
err.tries = tries;
|
|
181
|
+
throw err;
|
|
182
|
+
}
|
|
183
|
+
module.exports = exports = bindings;
|
|
184
|
+
exports.getFileName = function getFileName(calling_file) {
|
|
185
|
+
var origPST = Error.prepareStackTrace, origSTL = Error.stackTraceLimit, dummy = {}, fileName;
|
|
186
|
+
Error.stackTraceLimit = 10;
|
|
187
|
+
Error.prepareStackTrace = function(e, st) {
|
|
188
|
+
for (var i = 0, l = st.length; i < l; i++) {
|
|
189
|
+
fileName = st[i].getFileName();
|
|
190
|
+
if (fileName !== __filename) {
|
|
191
|
+
if (calling_file) {
|
|
192
|
+
if (fileName !== calling_file) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
} else {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
Error.captureStackTrace(dummy);
|
|
202
|
+
dummy.stack;
|
|
203
|
+
Error.prepareStackTrace = origPST;
|
|
204
|
+
Error.stackTraceLimit = origSTL;
|
|
205
|
+
var fileSchema = "file://";
|
|
206
|
+
if (fileName.indexOf(fileSchema) === 0) {
|
|
207
|
+
fileName = fileURLToPath(fileName);
|
|
208
|
+
}
|
|
209
|
+
return fileName;
|
|
210
|
+
};
|
|
211
|
+
exports.getRoot = function getRoot(file) {
|
|
212
|
+
var dir = dirname(file), prev;
|
|
213
|
+
while (true) {
|
|
214
|
+
if (dir === ".") {
|
|
215
|
+
dir = process.cwd();
|
|
216
|
+
}
|
|
217
|
+
if (exists(join3(dir, "package.json")) || exists(join3(dir, "node_modules"))) {
|
|
218
|
+
return dir;
|
|
219
|
+
}
|
|
220
|
+
if (prev === dir) {
|
|
221
|
+
throw new Error(
|
|
222
|
+
'Could not find module root given file: "' + file + '". Do you have a `package.json` file? '
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
prev = dir;
|
|
226
|
+
dir = join3(dir, "..");
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/wrappers.js
|
|
233
|
+
var require_wrappers = __commonJS({
|
|
234
|
+
"../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/wrappers.js"(exports) {
|
|
235
|
+
"use strict";
|
|
236
|
+
var { cppdb } = require_util();
|
|
237
|
+
exports.prepare = function prepare(sql) {
|
|
238
|
+
return this[cppdb].prepare(sql, this, false);
|
|
239
|
+
};
|
|
240
|
+
exports.exec = function exec(sql) {
|
|
241
|
+
this[cppdb].exec(sql);
|
|
242
|
+
return this;
|
|
243
|
+
};
|
|
244
|
+
exports.close = function close() {
|
|
245
|
+
this[cppdb].close();
|
|
246
|
+
return this;
|
|
247
|
+
};
|
|
248
|
+
exports.loadExtension = function loadExtension(...args) {
|
|
249
|
+
this[cppdb].loadExtension(...args);
|
|
250
|
+
return this;
|
|
251
|
+
};
|
|
252
|
+
exports.defaultSafeIntegers = function defaultSafeIntegers(...args) {
|
|
253
|
+
this[cppdb].defaultSafeIntegers(...args);
|
|
254
|
+
return this;
|
|
255
|
+
};
|
|
256
|
+
exports.unsafeMode = function unsafeMode(...args) {
|
|
257
|
+
this[cppdb].unsafeMode(...args);
|
|
258
|
+
return this;
|
|
259
|
+
};
|
|
260
|
+
exports.getters = {
|
|
261
|
+
name: {
|
|
262
|
+
get: function name() {
|
|
263
|
+
return this[cppdb].name;
|
|
264
|
+
},
|
|
265
|
+
enumerable: true
|
|
266
|
+
},
|
|
267
|
+
open: {
|
|
268
|
+
get: function open() {
|
|
269
|
+
return this[cppdb].open;
|
|
270
|
+
},
|
|
271
|
+
enumerable: true
|
|
272
|
+
},
|
|
273
|
+
inTransaction: {
|
|
274
|
+
get: function inTransaction() {
|
|
275
|
+
return this[cppdb].inTransaction;
|
|
276
|
+
},
|
|
277
|
+
enumerable: true
|
|
278
|
+
},
|
|
279
|
+
readonly: {
|
|
280
|
+
get: function readonly() {
|
|
281
|
+
return this[cppdb].readonly;
|
|
282
|
+
},
|
|
283
|
+
enumerable: true
|
|
284
|
+
},
|
|
285
|
+
memory: {
|
|
286
|
+
get: function memory() {
|
|
287
|
+
return this[cppdb].memory;
|
|
288
|
+
},
|
|
289
|
+
enumerable: true
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
// ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/transaction.js
|
|
296
|
+
var require_transaction = __commonJS({
|
|
297
|
+
"../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/transaction.js"(exports, module) {
|
|
298
|
+
"use strict";
|
|
299
|
+
var { cppdb } = require_util();
|
|
300
|
+
var controllers = /* @__PURE__ */ new WeakMap();
|
|
301
|
+
module.exports = function transaction(fn) {
|
|
302
|
+
if (typeof fn !== "function") throw new TypeError("Expected first argument to be a function");
|
|
303
|
+
const db = this[cppdb];
|
|
304
|
+
const controller = getController(db, this);
|
|
305
|
+
const { apply } = Function.prototype;
|
|
306
|
+
const properties = {
|
|
307
|
+
default: { value: wrapTransaction(apply, fn, db, controller.default) },
|
|
308
|
+
deferred: { value: wrapTransaction(apply, fn, db, controller.deferred) },
|
|
309
|
+
immediate: { value: wrapTransaction(apply, fn, db, controller.immediate) },
|
|
310
|
+
exclusive: { value: wrapTransaction(apply, fn, db, controller.exclusive) },
|
|
311
|
+
database: { value: this, enumerable: true }
|
|
312
|
+
};
|
|
313
|
+
Object.defineProperties(properties.default.value, properties);
|
|
314
|
+
Object.defineProperties(properties.deferred.value, properties);
|
|
315
|
+
Object.defineProperties(properties.immediate.value, properties);
|
|
316
|
+
Object.defineProperties(properties.exclusive.value, properties);
|
|
317
|
+
return properties.default.value;
|
|
318
|
+
};
|
|
319
|
+
var getController = (db, self) => {
|
|
320
|
+
let controller = controllers.get(db);
|
|
321
|
+
if (!controller) {
|
|
322
|
+
const shared = {
|
|
323
|
+
commit: db.prepare("COMMIT", self, false),
|
|
324
|
+
rollback: db.prepare("ROLLBACK", self, false),
|
|
325
|
+
savepoint: db.prepare("SAVEPOINT ` _bs3. `", self, false),
|
|
326
|
+
release: db.prepare("RELEASE ` _bs3. `", self, false),
|
|
327
|
+
rollbackTo: db.prepare("ROLLBACK TO ` _bs3. `", self, false)
|
|
328
|
+
};
|
|
329
|
+
controllers.set(db, controller = {
|
|
330
|
+
default: Object.assign({ begin: db.prepare("BEGIN", self, false) }, shared),
|
|
331
|
+
deferred: Object.assign({ begin: db.prepare("BEGIN DEFERRED", self, false) }, shared),
|
|
332
|
+
immediate: Object.assign({ begin: db.prepare("BEGIN IMMEDIATE", self, false) }, shared),
|
|
333
|
+
exclusive: Object.assign({ begin: db.prepare("BEGIN EXCLUSIVE", self, false) }, shared)
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
return controller;
|
|
337
|
+
};
|
|
338
|
+
var wrapTransaction = (apply, fn, db, { begin, commit, rollback, savepoint, release, rollbackTo }) => function sqliteTransaction() {
|
|
339
|
+
let before, after, undo;
|
|
340
|
+
if (db.inTransaction) {
|
|
341
|
+
before = savepoint;
|
|
342
|
+
after = release;
|
|
343
|
+
undo = rollbackTo;
|
|
344
|
+
} else {
|
|
345
|
+
before = begin;
|
|
346
|
+
after = commit;
|
|
347
|
+
undo = rollback;
|
|
348
|
+
}
|
|
349
|
+
before.run();
|
|
350
|
+
try {
|
|
351
|
+
const result = apply.call(fn, this, arguments);
|
|
352
|
+
if (result && typeof result.then === "function") {
|
|
353
|
+
throw new TypeError("Transaction function cannot return a promise");
|
|
354
|
+
}
|
|
355
|
+
after.run();
|
|
356
|
+
return result;
|
|
357
|
+
} catch (ex) {
|
|
358
|
+
if (db.inTransaction) {
|
|
359
|
+
undo.run();
|
|
360
|
+
if (undo !== rollback) after.run();
|
|
361
|
+
}
|
|
362
|
+
throw ex;
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
// ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/pragma.js
|
|
369
|
+
var require_pragma = __commonJS({
|
|
370
|
+
"../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/pragma.js"(exports, module) {
|
|
371
|
+
"use strict";
|
|
372
|
+
var { getBooleanOption, cppdb } = require_util();
|
|
373
|
+
module.exports = function pragma(source, options) {
|
|
374
|
+
if (options == null) options = {};
|
|
375
|
+
if (typeof source !== "string") throw new TypeError("Expected first argument to be a string");
|
|
376
|
+
if (typeof options !== "object") throw new TypeError("Expected second argument to be an options object");
|
|
377
|
+
const simple = getBooleanOption(options, "simple");
|
|
378
|
+
const stmt = this[cppdb].prepare(`PRAGMA ${source}`, this, true);
|
|
379
|
+
return simple ? stmt.pluck().get() : stmt.all();
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
// ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/backup.js
|
|
385
|
+
var require_backup = __commonJS({
|
|
386
|
+
"../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/backup.js"(exports, module) {
|
|
387
|
+
"use strict";
|
|
388
|
+
var fs3 = __require("fs");
|
|
389
|
+
var path2 = __require("path");
|
|
390
|
+
var { promisify } = __require("util");
|
|
391
|
+
var { cppdb } = require_util();
|
|
392
|
+
var fsAccess = promisify(fs3.access);
|
|
393
|
+
module.exports = async function backup(filename, options) {
|
|
394
|
+
if (options == null) options = {};
|
|
395
|
+
if (typeof filename !== "string") throw new TypeError("Expected first argument to be a string");
|
|
396
|
+
if (typeof options !== "object") throw new TypeError("Expected second argument to be an options object");
|
|
397
|
+
filename = filename.trim();
|
|
398
|
+
const attachedName = "attached" in options ? options.attached : "main";
|
|
399
|
+
const handler = "progress" in options ? options.progress : null;
|
|
400
|
+
if (!filename) throw new TypeError("Backup filename cannot be an empty string");
|
|
401
|
+
if (filename === ":memory:") throw new TypeError('Invalid backup filename ":memory:"');
|
|
402
|
+
if (typeof attachedName !== "string") throw new TypeError('Expected the "attached" option to be a string');
|
|
403
|
+
if (!attachedName) throw new TypeError('The "attached" option cannot be an empty string');
|
|
404
|
+
if (handler != null && typeof handler !== "function") throw new TypeError('Expected the "progress" option to be a function');
|
|
405
|
+
await fsAccess(path2.dirname(filename)).catch(() => {
|
|
406
|
+
throw new TypeError("Cannot save backup because the directory does not exist");
|
|
407
|
+
});
|
|
408
|
+
const isNewFile = await fsAccess(filename).then(() => false, () => true);
|
|
409
|
+
return runBackup(this[cppdb].backup(this, attachedName, filename, isNewFile), handler || null);
|
|
410
|
+
};
|
|
411
|
+
var runBackup = (backup, handler) => {
|
|
412
|
+
let rate = 0;
|
|
413
|
+
let useDefault = true;
|
|
414
|
+
return new Promise((resolve, reject) => {
|
|
415
|
+
setImmediate(function step() {
|
|
416
|
+
try {
|
|
417
|
+
const progress = backup.transfer(rate);
|
|
418
|
+
if (!progress.remainingPages) {
|
|
419
|
+
backup.close();
|
|
420
|
+
resolve(progress);
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
if (useDefault) {
|
|
424
|
+
useDefault = false;
|
|
425
|
+
rate = 100;
|
|
426
|
+
}
|
|
427
|
+
if (handler) {
|
|
428
|
+
const ret = handler(progress);
|
|
429
|
+
if (ret !== void 0) {
|
|
430
|
+
if (typeof ret === "number" && ret === ret) rate = Math.max(0, Math.min(2147483647, Math.round(ret)));
|
|
431
|
+
else throw new TypeError("Expected progress callback to return a number or undefined");
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
setImmediate(step);
|
|
435
|
+
} catch (err) {
|
|
436
|
+
backup.close();
|
|
437
|
+
reject(err);
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
});
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
// ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/serialize.js
|
|
446
|
+
var require_serialize = __commonJS({
|
|
447
|
+
"../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/serialize.js"(exports, module) {
|
|
448
|
+
"use strict";
|
|
449
|
+
var { cppdb } = require_util();
|
|
450
|
+
module.exports = function serialize(options) {
|
|
451
|
+
if (options == null) options = {};
|
|
452
|
+
if (typeof options !== "object") throw new TypeError("Expected first argument to be an options object");
|
|
453
|
+
const attachedName = "attached" in options ? options.attached : "main";
|
|
454
|
+
if (typeof attachedName !== "string") throw new TypeError('Expected the "attached" option to be a string');
|
|
455
|
+
if (!attachedName) throw new TypeError('The "attached" option cannot be an empty string');
|
|
456
|
+
return this[cppdb].serialize(attachedName);
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
// ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/function.js
|
|
462
|
+
var require_function = __commonJS({
|
|
463
|
+
"../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/function.js"(exports, module) {
|
|
464
|
+
"use strict";
|
|
465
|
+
var { getBooleanOption, cppdb } = require_util();
|
|
466
|
+
module.exports = function defineFunction(name, options, fn) {
|
|
467
|
+
if (options == null) options = {};
|
|
468
|
+
if (typeof options === "function") {
|
|
469
|
+
fn = options;
|
|
470
|
+
options = {};
|
|
471
|
+
}
|
|
472
|
+
if (typeof name !== "string") throw new TypeError("Expected first argument to be a string");
|
|
473
|
+
if (typeof fn !== "function") throw new TypeError("Expected last argument to be a function");
|
|
474
|
+
if (typeof options !== "object") throw new TypeError("Expected second argument to be an options object");
|
|
475
|
+
if (!name) throw new TypeError("User-defined function name cannot be an empty string");
|
|
476
|
+
const safeIntegers = "safeIntegers" in options ? +getBooleanOption(options, "safeIntegers") : 2;
|
|
477
|
+
const deterministic = getBooleanOption(options, "deterministic");
|
|
478
|
+
const directOnly = getBooleanOption(options, "directOnly");
|
|
479
|
+
const varargs = getBooleanOption(options, "varargs");
|
|
480
|
+
let argCount = -1;
|
|
481
|
+
if (!varargs) {
|
|
482
|
+
argCount = fn.length;
|
|
483
|
+
if (!Number.isInteger(argCount) || argCount < 0) throw new TypeError("Expected function.length to be a positive integer");
|
|
484
|
+
if (argCount > 100) throw new RangeError("User-defined functions cannot have more than 100 arguments");
|
|
485
|
+
}
|
|
486
|
+
this[cppdb].function(fn, name, argCount, safeIntegers, deterministic, directOnly);
|
|
487
|
+
return this;
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
// ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/aggregate.js
|
|
493
|
+
var require_aggregate = __commonJS({
|
|
494
|
+
"../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/aggregate.js"(exports, module) {
|
|
495
|
+
"use strict";
|
|
496
|
+
var { getBooleanOption, cppdb } = require_util();
|
|
497
|
+
module.exports = function defineAggregate(name, options) {
|
|
498
|
+
if (typeof name !== "string") throw new TypeError("Expected first argument to be a string");
|
|
499
|
+
if (typeof options !== "object" || options === null) throw new TypeError("Expected second argument to be an options object");
|
|
500
|
+
if (!name) throw new TypeError("User-defined function name cannot be an empty string");
|
|
501
|
+
const start = "start" in options ? options.start : null;
|
|
502
|
+
const step = getFunctionOption(options, "step", true);
|
|
503
|
+
const inverse = getFunctionOption(options, "inverse", false);
|
|
504
|
+
const result = getFunctionOption(options, "result", false);
|
|
505
|
+
const safeIntegers = "safeIntegers" in options ? +getBooleanOption(options, "safeIntegers") : 2;
|
|
506
|
+
const deterministic = getBooleanOption(options, "deterministic");
|
|
507
|
+
const directOnly = getBooleanOption(options, "directOnly");
|
|
508
|
+
const varargs = getBooleanOption(options, "varargs");
|
|
509
|
+
let argCount = -1;
|
|
510
|
+
if (!varargs) {
|
|
511
|
+
argCount = Math.max(getLength(step), inverse ? getLength(inverse) : 0);
|
|
512
|
+
if (argCount > 0) argCount -= 1;
|
|
513
|
+
if (argCount > 100) throw new RangeError("User-defined functions cannot have more than 100 arguments");
|
|
514
|
+
}
|
|
515
|
+
this[cppdb].aggregate(start, step, inverse, result, name, argCount, safeIntegers, deterministic, directOnly);
|
|
516
|
+
return this;
|
|
517
|
+
};
|
|
518
|
+
var getFunctionOption = (options, key, required) => {
|
|
519
|
+
const value = key in options ? options[key] : null;
|
|
520
|
+
if (typeof value === "function") return value;
|
|
521
|
+
if (value != null) throw new TypeError(`Expected the "${key}" option to be a function`);
|
|
522
|
+
if (required) throw new TypeError(`Missing required option "${key}"`);
|
|
523
|
+
return null;
|
|
524
|
+
};
|
|
525
|
+
var getLength = ({ length }) => {
|
|
526
|
+
if (Number.isInteger(length) && length >= 0) return length;
|
|
527
|
+
throw new TypeError("Expected function.length to be a positive integer");
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
// ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/table.js
|
|
533
|
+
var require_table = __commonJS({
|
|
534
|
+
"../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/table.js"(exports, module) {
|
|
535
|
+
"use strict";
|
|
536
|
+
var { cppdb } = require_util();
|
|
537
|
+
module.exports = function defineTable(name, factory) {
|
|
538
|
+
if (typeof name !== "string") throw new TypeError("Expected first argument to be a string");
|
|
539
|
+
if (!name) throw new TypeError("Virtual table module name cannot be an empty string");
|
|
540
|
+
let eponymous = false;
|
|
541
|
+
if (typeof factory === "object" && factory !== null) {
|
|
542
|
+
eponymous = true;
|
|
543
|
+
factory = defer(parseTableDefinition(factory, "used", name));
|
|
544
|
+
} else {
|
|
545
|
+
if (typeof factory !== "function") throw new TypeError("Expected second argument to be a function or a table definition object");
|
|
546
|
+
factory = wrapFactory(factory);
|
|
547
|
+
}
|
|
548
|
+
this[cppdb].table(factory, name, eponymous);
|
|
549
|
+
return this;
|
|
550
|
+
};
|
|
551
|
+
function wrapFactory(factory) {
|
|
552
|
+
return function virtualTableFactory(moduleName, databaseName, tableName, ...args) {
|
|
553
|
+
const thisObject = {
|
|
554
|
+
module: moduleName,
|
|
555
|
+
database: databaseName,
|
|
556
|
+
table: tableName
|
|
557
|
+
};
|
|
558
|
+
const def = apply.call(factory, thisObject, args);
|
|
559
|
+
if (typeof def !== "object" || def === null) {
|
|
560
|
+
throw new TypeError(`Virtual table module "${moduleName}" did not return a table definition object`);
|
|
561
|
+
}
|
|
562
|
+
return parseTableDefinition(def, "returned", moduleName);
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
function parseTableDefinition(def, verb, moduleName) {
|
|
566
|
+
if (!hasOwnProperty.call(def, "rows")) {
|
|
567
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "rows" property`);
|
|
568
|
+
}
|
|
569
|
+
if (!hasOwnProperty.call(def, "columns")) {
|
|
570
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "columns" property`);
|
|
571
|
+
}
|
|
572
|
+
const rows = def.rows;
|
|
573
|
+
if (typeof rows !== "function" || Object.getPrototypeOf(rows) !== GeneratorFunctionPrototype) {
|
|
574
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "rows" property (should be a generator function)`);
|
|
575
|
+
}
|
|
576
|
+
let columns = def.columns;
|
|
577
|
+
if (!Array.isArray(columns) || !(columns = [...columns]).every((x) => typeof x === "string")) {
|
|
578
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "columns" property (should be an array of strings)`);
|
|
579
|
+
}
|
|
580
|
+
if (columns.length !== new Set(columns).size) {
|
|
581
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate column names`);
|
|
582
|
+
}
|
|
583
|
+
if (!columns.length) {
|
|
584
|
+
throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with zero columns`);
|
|
585
|
+
}
|
|
586
|
+
let parameters;
|
|
587
|
+
if (hasOwnProperty.call(def, "parameters")) {
|
|
588
|
+
parameters = def.parameters;
|
|
589
|
+
if (!Array.isArray(parameters) || !(parameters = [...parameters]).every((x) => typeof x === "string")) {
|
|
590
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "parameters" property (should be an array of strings)`);
|
|
591
|
+
}
|
|
592
|
+
} else {
|
|
593
|
+
parameters = inferParameters(rows);
|
|
594
|
+
}
|
|
595
|
+
if (parameters.length !== new Set(parameters).size) {
|
|
596
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate parameter names`);
|
|
597
|
+
}
|
|
598
|
+
if (parameters.length > 32) {
|
|
599
|
+
throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with more than the maximum number of 32 parameters`);
|
|
600
|
+
}
|
|
601
|
+
for (const parameter of parameters) {
|
|
602
|
+
if (columns.includes(parameter)) {
|
|
603
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with column "${parameter}" which was ambiguously defined as both a column and parameter`);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
let safeIntegers = 2;
|
|
607
|
+
if (hasOwnProperty.call(def, "safeIntegers")) {
|
|
608
|
+
const bool = def.safeIntegers;
|
|
609
|
+
if (typeof bool !== "boolean") {
|
|
610
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "safeIntegers" property (should be a boolean)`);
|
|
611
|
+
}
|
|
612
|
+
safeIntegers = +bool;
|
|
613
|
+
}
|
|
614
|
+
let directOnly = false;
|
|
615
|
+
if (hasOwnProperty.call(def, "directOnly")) {
|
|
616
|
+
directOnly = def.directOnly;
|
|
617
|
+
if (typeof directOnly !== "boolean") {
|
|
618
|
+
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "directOnly" property (should be a boolean)`);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
const columnDefinitions = [
|
|
622
|
+
...parameters.map(identifier).map((str) => `${str} HIDDEN`),
|
|
623
|
+
...columns.map(identifier)
|
|
624
|
+
];
|
|
625
|
+
return [
|
|
626
|
+
`CREATE TABLE x(${columnDefinitions.join(", ")});`,
|
|
627
|
+
wrapGenerator(rows, new Map(columns.map((x, i) => [x, parameters.length + i])), moduleName),
|
|
628
|
+
parameters,
|
|
629
|
+
safeIntegers,
|
|
630
|
+
directOnly
|
|
631
|
+
];
|
|
632
|
+
}
|
|
633
|
+
function wrapGenerator(generator, columnMap, moduleName) {
|
|
634
|
+
return function* virtualTable(...args) {
|
|
635
|
+
const output = args.map((x) => Buffer.isBuffer(x) ? Buffer.from(x) : x);
|
|
636
|
+
for (let i = 0; i < columnMap.size; ++i) {
|
|
637
|
+
output.push(null);
|
|
638
|
+
}
|
|
639
|
+
for (const row of generator(...args)) {
|
|
640
|
+
if (Array.isArray(row)) {
|
|
641
|
+
extractRowArray(row, output, columnMap.size, moduleName);
|
|
642
|
+
yield output;
|
|
643
|
+
} else if (typeof row === "object" && row !== null) {
|
|
644
|
+
extractRowObject(row, output, columnMap, moduleName);
|
|
645
|
+
yield output;
|
|
646
|
+
} else {
|
|
647
|
+
throw new TypeError(`Virtual table module "${moduleName}" yielded something that isn't a valid row object`);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
function extractRowArray(row, output, columnCount, moduleName) {
|
|
653
|
+
if (row.length !== columnCount) {
|
|
654
|
+
throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an incorrect number of columns`);
|
|
655
|
+
}
|
|
656
|
+
const offset = output.length - columnCount;
|
|
657
|
+
for (let i = 0; i < columnCount; ++i) {
|
|
658
|
+
output[i + offset] = row[i];
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
function extractRowObject(row, output, columnMap, moduleName) {
|
|
662
|
+
let count = 0;
|
|
663
|
+
for (const key of Object.keys(row)) {
|
|
664
|
+
const index = columnMap.get(key);
|
|
665
|
+
if (index === void 0) {
|
|
666
|
+
throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an undeclared column "${key}"`);
|
|
667
|
+
}
|
|
668
|
+
output[index] = row[key];
|
|
669
|
+
count += 1;
|
|
670
|
+
}
|
|
671
|
+
if (count !== columnMap.size) {
|
|
672
|
+
throw new TypeError(`Virtual table module "${moduleName}" yielded a row with missing columns`);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
function inferParameters({ length }) {
|
|
676
|
+
if (!Number.isInteger(length) || length < 0) {
|
|
677
|
+
throw new TypeError("Expected function.length to be a positive integer");
|
|
678
|
+
}
|
|
679
|
+
const params = [];
|
|
680
|
+
for (let i = 0; i < length; ++i) {
|
|
681
|
+
params.push(`$${i + 1}`);
|
|
682
|
+
}
|
|
683
|
+
return params;
|
|
684
|
+
}
|
|
685
|
+
var { hasOwnProperty } = Object.prototype;
|
|
686
|
+
var { apply } = Function.prototype;
|
|
687
|
+
var GeneratorFunctionPrototype = Object.getPrototypeOf(function* () {
|
|
688
|
+
});
|
|
689
|
+
var identifier = (str) => `"${str.replace(/"/g, '""')}"`;
|
|
690
|
+
var defer = (x) => () => x;
|
|
691
|
+
}
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
// ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/inspect.js
|
|
695
|
+
var require_inspect = __commonJS({
|
|
696
|
+
"../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/inspect.js"(exports, module) {
|
|
697
|
+
"use strict";
|
|
698
|
+
var DatabaseInspection = function Database2() {
|
|
699
|
+
};
|
|
700
|
+
module.exports = function inspect(depth, opts) {
|
|
701
|
+
return Object.assign(new DatabaseInspection(), this);
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
});
|
|
705
|
+
|
|
706
|
+
// ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/database.js
|
|
707
|
+
var require_database = __commonJS({
|
|
708
|
+
"../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/database.js"(exports, module) {
|
|
709
|
+
"use strict";
|
|
710
|
+
var fs3 = __require("fs");
|
|
711
|
+
var path2 = __require("path");
|
|
712
|
+
var util = require_util();
|
|
713
|
+
var SqliteError = require_sqlite_error();
|
|
714
|
+
var DEFAULT_ADDON;
|
|
715
|
+
function Database2(filenameGiven, options) {
|
|
716
|
+
if (new.target == null) {
|
|
717
|
+
return new Database2(filenameGiven, options);
|
|
718
|
+
}
|
|
719
|
+
let buffer;
|
|
720
|
+
if (Buffer.isBuffer(filenameGiven)) {
|
|
721
|
+
buffer = filenameGiven;
|
|
722
|
+
filenameGiven = ":memory:";
|
|
723
|
+
}
|
|
724
|
+
if (filenameGiven == null) filenameGiven = "";
|
|
725
|
+
if (options == null) options = {};
|
|
726
|
+
if (typeof filenameGiven !== "string") throw new TypeError("Expected first argument to be a string");
|
|
727
|
+
if (typeof options !== "object") throw new TypeError("Expected second argument to be an options object");
|
|
728
|
+
if ("readOnly" in options) throw new TypeError('Misspelled option "readOnly" should be "readonly"');
|
|
729
|
+
if ("memory" in options) throw new TypeError('Option "memory" was removed in v7.0.0 (use ":memory:" filename instead)');
|
|
730
|
+
const filename = filenameGiven.trim();
|
|
731
|
+
const anonymous = filename === "" || filename === ":memory:";
|
|
732
|
+
const readonly = util.getBooleanOption(options, "readonly");
|
|
733
|
+
const fileMustExist = util.getBooleanOption(options, "fileMustExist");
|
|
734
|
+
const timeout = "timeout" in options ? options.timeout : 5e3;
|
|
735
|
+
const verbose = "verbose" in options ? options.verbose : null;
|
|
736
|
+
const nativeBinding = "nativeBinding" in options ? options.nativeBinding : null;
|
|
737
|
+
if (readonly && anonymous && !buffer) throw new TypeError("In-memory/temporary databases cannot be readonly");
|
|
738
|
+
if (!Number.isInteger(timeout) || timeout < 0) throw new TypeError('Expected the "timeout" option to be a positive integer');
|
|
739
|
+
if (timeout > 2147483647) throw new RangeError('Option "timeout" cannot be greater than 2147483647');
|
|
740
|
+
if (verbose != null && typeof verbose !== "function") throw new TypeError('Expected the "verbose" option to be a function');
|
|
741
|
+
if (nativeBinding != null && typeof nativeBinding !== "string" && typeof nativeBinding !== "object") throw new TypeError('Expected the "nativeBinding" option to be a string or addon object');
|
|
742
|
+
let addon;
|
|
743
|
+
if (nativeBinding == null) {
|
|
744
|
+
addon = DEFAULT_ADDON || (DEFAULT_ADDON = require_bindings()("better_sqlite3.node"));
|
|
745
|
+
} else if (typeof nativeBinding === "string") {
|
|
746
|
+
const requireFunc = typeof __non_webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
747
|
+
addon = requireFunc(path2.resolve(nativeBinding).replace(/(\.node)?$/, ".node"));
|
|
748
|
+
} else {
|
|
749
|
+
addon = nativeBinding;
|
|
750
|
+
}
|
|
751
|
+
if (!addon.isInitialized) {
|
|
752
|
+
addon.setErrorConstructor(SqliteError);
|
|
753
|
+
addon.isInitialized = true;
|
|
754
|
+
}
|
|
755
|
+
if (!anonymous && !fs3.existsSync(path2.dirname(filename))) {
|
|
756
|
+
throw new TypeError("Cannot open database because the directory does not exist");
|
|
757
|
+
}
|
|
758
|
+
Object.defineProperties(this, {
|
|
759
|
+
[util.cppdb]: { value: new addon.Database(filename, filenameGiven, anonymous, readonly, fileMustExist, timeout, verbose || null, buffer || null) },
|
|
760
|
+
...wrappers.getters
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
var wrappers = require_wrappers();
|
|
764
|
+
Database2.prototype.prepare = wrappers.prepare;
|
|
765
|
+
Database2.prototype.transaction = require_transaction();
|
|
766
|
+
Database2.prototype.pragma = require_pragma();
|
|
767
|
+
Database2.prototype.backup = require_backup();
|
|
768
|
+
Database2.prototype.serialize = require_serialize();
|
|
769
|
+
Database2.prototype.function = require_function();
|
|
770
|
+
Database2.prototype.aggregate = require_aggregate();
|
|
771
|
+
Database2.prototype.table = require_table();
|
|
772
|
+
Database2.prototype.loadExtension = wrappers.loadExtension;
|
|
773
|
+
Database2.prototype.exec = wrappers.exec;
|
|
774
|
+
Database2.prototype.close = wrappers.close;
|
|
775
|
+
Database2.prototype.defaultSafeIntegers = wrappers.defaultSafeIntegers;
|
|
776
|
+
Database2.prototype.unsafeMode = wrappers.unsafeMode;
|
|
777
|
+
Database2.prototype[util.inspect] = require_inspect();
|
|
778
|
+
module.exports = Database2;
|
|
779
|
+
}
|
|
780
|
+
});
|
|
781
|
+
|
|
782
|
+
// ../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/index.js
|
|
783
|
+
var require_lib = __commonJS({
|
|
784
|
+
"../../node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/index.js"(exports, module) {
|
|
785
|
+
"use strict";
|
|
786
|
+
module.exports = require_database();
|
|
787
|
+
module.exports.SqliteError = require_sqlite_error();
|
|
788
|
+
}
|
|
789
|
+
});
|
|
12
790
|
|
|
13
791
|
// src/storage.ts
|
|
14
792
|
import { existsSync, mkdirSync } from "fs";
|
|
@@ -26,98 +804,70 @@ function detectPlurStorage(explicitPath) {
|
|
|
26
804
|
candidates: join(root, "candidates.yaml"),
|
|
27
805
|
packs: packsDir,
|
|
28
806
|
exchange: join(root, "exchange"),
|
|
29
|
-
config: join(root, "config.yaml")
|
|
807
|
+
config: join(root, "config.yaml"),
|
|
808
|
+
db: join(root, "engrams.db")
|
|
30
809
|
};
|
|
31
810
|
}
|
|
32
811
|
|
|
33
|
-
// src/
|
|
34
|
-
import { existsSync as
|
|
35
|
-
import yaml from "js-yaml";
|
|
36
|
-
|
|
37
|
-
// src/schemas/config.ts
|
|
38
|
-
import { z } from "zod";
|
|
39
|
-
var PlurConfigSchema = z.object({
|
|
40
|
-
auto_learn: z.boolean().default(true),
|
|
41
|
-
auto_capture: z.boolean().default(true),
|
|
42
|
-
injection_budget: z.number().default(2e3),
|
|
43
|
-
decay_enabled: z.boolean().default(true),
|
|
44
|
-
decay_threshold: z.number().default(0.15),
|
|
45
|
-
packs: z.array(z.string()).default([]),
|
|
46
|
-
injection: z.object({
|
|
47
|
-
spread_cap: z.number().default(3),
|
|
48
|
-
spread_budget: z.number().default(480),
|
|
49
|
-
co_access: z.boolean().default(true)
|
|
50
|
-
}).default({}),
|
|
51
|
-
allow_secrets: z.boolean().default(false)
|
|
52
|
-
}).partial();
|
|
53
|
-
|
|
54
|
-
// src/config.ts
|
|
55
|
-
function loadConfig(configPath) {
|
|
56
|
-
if (!existsSync2(configPath)) return PlurConfigSchema.parse({});
|
|
57
|
-
try {
|
|
58
|
-
const raw = yaml.load(readFileSync(configPath, "utf8"));
|
|
59
|
-
return PlurConfigSchema.parse(raw ?? {});
|
|
60
|
-
} catch {
|
|
61
|
-
return PlurConfigSchema.parse({});
|
|
62
|
-
}
|
|
63
|
-
}
|
|
812
|
+
// src/storage-indexed.ts
|
|
813
|
+
import { existsSync as existsSync3 } from "fs";
|
|
64
814
|
|
|
65
815
|
// src/engrams.ts
|
|
66
816
|
import * as fs from "fs";
|
|
67
|
-
import * as
|
|
817
|
+
import * as yaml from "js-yaml";
|
|
68
818
|
|
|
69
819
|
// src/schemas/engram.ts
|
|
70
|
-
import { z
|
|
71
|
-
var ActivationSchema =
|
|
72
|
-
retrieval_strength:
|
|
73
|
-
storage_strength:
|
|
74
|
-
frequency:
|
|
75
|
-
last_accessed:
|
|
820
|
+
import { z } from "zod";
|
|
821
|
+
var ActivationSchema = z.object({
|
|
822
|
+
retrieval_strength: z.number().min(0).max(1),
|
|
823
|
+
storage_strength: z.number().min(0).max(1),
|
|
824
|
+
frequency: z.number().int().min(0),
|
|
825
|
+
last_accessed: z.string()
|
|
76
826
|
});
|
|
77
|
-
var KnowledgeTypeSchema =
|
|
78
|
-
memory_class:
|
|
79
|
-
cognitive_level:
|
|
827
|
+
var KnowledgeTypeSchema = z.object({
|
|
828
|
+
memory_class: z.enum(["semantic", "episodic", "procedural", "metacognitive"]),
|
|
829
|
+
cognitive_level: z.enum(["remember", "understand", "apply", "analyze", "evaluate", "create"])
|
|
80
830
|
});
|
|
81
|
-
var KnowledgeAnchorSchema =
|
|
82
|
-
path:
|
|
83
|
-
relevance:
|
|
84
|
-
snippet:
|
|
85
|
-
snippet_extracted_at:
|
|
831
|
+
var KnowledgeAnchorSchema = z.object({
|
|
832
|
+
path: z.string(),
|
|
833
|
+
relevance: z.enum(["primary", "supporting", "example"]).default("supporting"),
|
|
834
|
+
snippet: z.string().max(200).optional(),
|
|
835
|
+
snippet_extracted_at: z.string().optional()
|
|
86
836
|
});
|
|
87
|
-
var AssociationSchema =
|
|
88
|
-
target_type:
|
|
89
|
-
target:
|
|
90
|
-
strength:
|
|
91
|
-
type:
|
|
92
|
-
updated_at:
|
|
837
|
+
var AssociationSchema = z.object({
|
|
838
|
+
target_type: z.enum(["engram", "document"]),
|
|
839
|
+
target: z.string(),
|
|
840
|
+
strength: z.number().min(0).max(0.95),
|
|
841
|
+
type: z.enum(["semantic", "temporal", "causal", "co_accessed"]),
|
|
842
|
+
updated_at: z.string().optional()
|
|
93
843
|
});
|
|
94
|
-
var DualCodingSchema =
|
|
95
|
-
example:
|
|
96
|
-
analogy:
|
|
844
|
+
var DualCodingSchema = z.object({
|
|
845
|
+
example: z.string().optional(),
|
|
846
|
+
analogy: z.string().optional()
|
|
97
847
|
}).refine(
|
|
98
848
|
(d) => d.example || d.analogy,
|
|
99
849
|
"At least one of example or analogy must be provided"
|
|
100
850
|
);
|
|
101
|
-
var RelationsSchema =
|
|
102
|
-
broader:
|
|
103
|
-
narrower:
|
|
104
|
-
related:
|
|
105
|
-
conflicts:
|
|
851
|
+
var RelationsSchema = z.object({
|
|
852
|
+
broader: z.array(z.string()).default([]),
|
|
853
|
+
narrower: z.array(z.string()).default([]),
|
|
854
|
+
related: z.array(z.string()).default([]),
|
|
855
|
+
conflicts: z.array(z.string()).default([])
|
|
106
856
|
});
|
|
107
|
-
var ProvenanceSchema =
|
|
108
|
-
origin:
|
|
109
|
-
chain:
|
|
110
|
-
signature:
|
|
111
|
-
license:
|
|
857
|
+
var ProvenanceSchema = z.object({
|
|
858
|
+
origin: z.string(),
|
|
859
|
+
chain: z.array(z.string()).default([]),
|
|
860
|
+
signature: z.string().nullable().default(null),
|
|
861
|
+
license: z.string().default("cc-by-sa-4.0")
|
|
112
862
|
});
|
|
113
|
-
var FeedbackSignalsSchema =
|
|
114
|
-
positive:
|
|
115
|
-
negative:
|
|
116
|
-
neutral:
|
|
863
|
+
var FeedbackSignalsSchema = z.object({
|
|
864
|
+
positive: z.number().int().default(0),
|
|
865
|
+
negative: z.number().int().default(0),
|
|
866
|
+
neutral: z.number().int().default(0)
|
|
117
867
|
});
|
|
118
|
-
var EntityRefSchema =
|
|
119
|
-
name:
|
|
120
|
-
type:
|
|
868
|
+
var EntityRefSchema = z.object({
|
|
869
|
+
name: z.string(),
|
|
870
|
+
type: z.enum([
|
|
121
871
|
"person",
|
|
122
872
|
"organization",
|
|
123
873
|
"technology",
|
|
@@ -129,56 +879,56 @@ var EntityRefSchema = z2.object({
|
|
|
129
879
|
"standard",
|
|
130
880
|
"other"
|
|
131
881
|
]),
|
|
132
|
-
uri:
|
|
882
|
+
uri: z.string().url().optional()
|
|
133
883
|
});
|
|
134
|
-
var TemporalSchema =
|
|
135
|
-
learned_at:
|
|
136
|
-
valid_from:
|
|
137
|
-
valid_until:
|
|
138
|
-
ingested_at:
|
|
884
|
+
var TemporalSchema = z.object({
|
|
885
|
+
learned_at: z.string(),
|
|
886
|
+
valid_from: z.string().optional(),
|
|
887
|
+
valid_until: z.string().optional(),
|
|
888
|
+
ingested_at: z.string().optional()
|
|
139
889
|
});
|
|
140
|
-
var UsageStatsSchema =
|
|
141
|
-
injections:
|
|
142
|
-
hits:
|
|
143
|
-
misses:
|
|
144
|
-
last_hit_at:
|
|
890
|
+
var UsageStatsSchema = z.object({
|
|
891
|
+
injections: z.number().int().default(0),
|
|
892
|
+
hits: z.number().int().default(0),
|
|
893
|
+
misses: z.number().int().default(0),
|
|
894
|
+
last_hit_at: z.string().optional()
|
|
145
895
|
});
|
|
146
|
-
var EpisodicFieldsSchema =
|
|
147
|
-
emotional_weight:
|
|
148
|
-
confidence:
|
|
149
|
-
trigger_context:
|
|
150
|
-
journal_ref:
|
|
896
|
+
var EpisodicFieldsSchema = z.object({
|
|
897
|
+
emotional_weight: z.number().int().min(1).max(10).default(5),
|
|
898
|
+
confidence: z.number().int().min(1).max(10).default(5),
|
|
899
|
+
trigger_context: z.string().optional(),
|
|
900
|
+
journal_ref: z.string().optional()
|
|
151
901
|
});
|
|
152
|
-
var ExchangeMetadataSchema =
|
|
153
|
-
fitness_score:
|
|
154
|
-
environmental_diversity:
|
|
155
|
-
adoption_count:
|
|
156
|
-
contradiction_rate:
|
|
902
|
+
var ExchangeMetadataSchema = z.object({
|
|
903
|
+
fitness_score: z.number().min(0).max(1).optional(),
|
|
904
|
+
environmental_diversity: z.number().int().default(0),
|
|
905
|
+
adoption_count: z.number().int().default(0),
|
|
906
|
+
contradiction_rate: z.number().min(0).max(1).default(0)
|
|
157
907
|
});
|
|
158
|
-
var EngramSchema =
|
|
908
|
+
var EngramSchema = z.object({
|
|
159
909
|
// Identity
|
|
160
|
-
id:
|
|
161
|
-
version:
|
|
162
|
-
status:
|
|
163
|
-
consolidated:
|
|
164
|
-
type:
|
|
165
|
-
scope:
|
|
166
|
-
visibility:
|
|
910
|
+
id: z.string().regex(/^(ENG|ABS|META)-[A-Za-z0-9-]+$/),
|
|
911
|
+
version: z.number().int().min(1).default(2),
|
|
912
|
+
status: z.enum(["active", "dormant", "retired", "candidate"]),
|
|
913
|
+
consolidated: z.boolean().default(false),
|
|
914
|
+
type: z.enum(["behavioral", "terminological", "procedural", "architectural"]),
|
|
915
|
+
scope: z.string(),
|
|
916
|
+
visibility: z.enum(["private", "public", "template"]).default("private"),
|
|
167
917
|
// Content
|
|
168
|
-
statement:
|
|
169
|
-
rationale:
|
|
170
|
-
contraindications:
|
|
918
|
+
statement: z.string().min(1),
|
|
919
|
+
rationale: z.string().optional(),
|
|
920
|
+
contraindications: z.array(z.string()).optional(),
|
|
171
921
|
// Lineage
|
|
172
|
-
source:
|
|
173
|
-
source_patterns:
|
|
174
|
-
derivation_count:
|
|
175
|
-
pack:
|
|
176
|
-
abstract:
|
|
177
|
-
derived_from:
|
|
922
|
+
source: z.string().optional(),
|
|
923
|
+
source_patterns: z.array(z.string()).optional(),
|
|
924
|
+
derivation_count: z.number().int().min(0).default(1),
|
|
925
|
+
pack: z.string().nullable().default(null),
|
|
926
|
+
abstract: z.string().nullable().default(null),
|
|
927
|
+
derived_from: z.string().nullable().default(null),
|
|
178
928
|
// Classification
|
|
179
929
|
knowledge_type: KnowledgeTypeSchema.optional(),
|
|
180
|
-
domain:
|
|
181
|
-
tags:
|
|
930
|
+
domain: z.string().optional(),
|
|
931
|
+
tags: z.array(z.string()).default([]),
|
|
182
932
|
// Activation (ACT-R model)
|
|
183
933
|
activation: ActivationSchema.default({
|
|
184
934
|
retrieval_strength: 0.7,
|
|
@@ -188,8 +938,8 @@ var EngramSchema = z2.object({
|
|
|
188
938
|
}),
|
|
189
939
|
// Relations & grounding
|
|
190
940
|
relations: RelationsSchema.optional(),
|
|
191
|
-
associations:
|
|
192
|
-
knowledge_anchors:
|
|
941
|
+
associations: z.array(AssociationSchema).default([]),
|
|
942
|
+
knowledge_anchors: z.array(KnowledgeAnchorSchema).default([]),
|
|
193
943
|
dual_coding: DualCodingSchema.optional(),
|
|
194
944
|
// Provenance
|
|
195
945
|
provenance: ProvenanceSchema.optional(),
|
|
@@ -197,7 +947,7 @@ var EngramSchema = z2.object({
|
|
|
197
947
|
feedback_signals: FeedbackSignalsSchema.default({ positive: 0, negative: 0, neutral: 0 }),
|
|
198
948
|
// === NEW OPTIONAL FIELDS (v2.1) ===
|
|
199
949
|
/** Typed entity references extracted from statement. Enables graph queries. */
|
|
200
|
-
entities:
|
|
950
|
+
entities: z.array(EntityRefSchema).optional(),
|
|
201
951
|
/** Temporal validity window. When is this knowledge true? */
|
|
202
952
|
temporal: TemporalSchema.optional(),
|
|
203
953
|
/** Automatic usage tracking. Injections, hits, misses. */
|
|
@@ -207,33 +957,33 @@ var EngramSchema = z2.object({
|
|
|
207
957
|
/** Exchange marketplace metadata: fitness, adoption, diversity. */
|
|
208
958
|
exchange: ExchangeMetadataSchema.optional(),
|
|
209
959
|
/** Extensible key-value data for domain-specific fields. */
|
|
210
|
-
structured_data:
|
|
960
|
+
structured_data: z.record(z.string(), z.unknown()).optional(),
|
|
211
961
|
/** Polarity classification: 'do' for directives, 'dont' for prohibitions, null for unclassified. */
|
|
212
|
-
polarity:
|
|
962
|
+
polarity: z.enum(["do", "dont"]).nullable().default(null)
|
|
213
963
|
});
|
|
214
964
|
|
|
215
965
|
// src/schemas/pack.ts
|
|
216
|
-
import { z as
|
|
217
|
-
var PackManifestSchema =
|
|
218
|
-
name:
|
|
219
|
-
version:
|
|
220
|
-
description:
|
|
221
|
-
creator:
|
|
222
|
-
license:
|
|
223
|
-
tags:
|
|
224
|
-
metadata:
|
|
225
|
-
id:
|
|
226
|
-
injection_policy:
|
|
227
|
-
match_terms:
|
|
228
|
-
domain:
|
|
229
|
-
engram_count:
|
|
966
|
+
import { z as z2 } from "zod";
|
|
967
|
+
var PackManifestSchema = z2.object({
|
|
968
|
+
name: z2.string(),
|
|
969
|
+
version: z2.string(),
|
|
970
|
+
description: z2.string().optional(),
|
|
971
|
+
creator: z2.string().optional(),
|
|
972
|
+
license: z2.string().default("cc-by-sa-4.0"),
|
|
973
|
+
tags: z2.array(z2.string()).default([]),
|
|
974
|
+
metadata: z2.object({
|
|
975
|
+
id: z2.string().optional(),
|
|
976
|
+
injection_policy: z2.enum(["on_match", "on_request", "always"]).default("on_match"),
|
|
977
|
+
match_terms: z2.array(z2.string()).default([]),
|
|
978
|
+
domain: z2.string().optional(),
|
|
979
|
+
engram_count: z2.number().optional()
|
|
230
980
|
}).optional(),
|
|
231
|
-
"x-datacore":
|
|
232
|
-
id:
|
|
233
|
-
injection_policy:
|
|
234
|
-
match_terms:
|
|
235
|
-
domain:
|
|
236
|
-
engram_count:
|
|
981
|
+
"x-datacore": z2.object({
|
|
982
|
+
id: z2.string(),
|
|
983
|
+
injection_policy: z2.enum(["on_match", "on_request"]),
|
|
984
|
+
match_terms: z2.array(z2.string()).default([]),
|
|
985
|
+
domain: z2.string().optional(),
|
|
986
|
+
engram_count: z2.number().int().min(0)
|
|
237
987
|
}).optional()
|
|
238
988
|
});
|
|
239
989
|
|
|
@@ -260,7 +1010,7 @@ var logger = {
|
|
|
260
1010
|
function loadEngrams(filePath) {
|
|
261
1011
|
if (!fs.existsSync(filePath)) return [];
|
|
262
1012
|
try {
|
|
263
|
-
const raw =
|
|
1013
|
+
const raw = yaml.load(fs.readFileSync(filePath, "utf8"));
|
|
264
1014
|
if (!raw?.engrams || !Array.isArray(raw.engrams)) return [];
|
|
265
1015
|
const valid = [];
|
|
266
1016
|
let skipped = 0;
|
|
@@ -277,14 +1027,14 @@ function loadEngrams(filePath) {
|
|
|
277
1027
|
}
|
|
278
1028
|
}
|
|
279
1029
|
function saveEngrams(filePath, engrams) {
|
|
280
|
-
const content =
|
|
1030
|
+
const content = yaml.dump({ engrams }, { lineWidth: 120, noRefs: true, quotingType: '"' });
|
|
281
1031
|
atomicWrite(filePath, content);
|
|
282
1032
|
}
|
|
283
1033
|
function parseSkillMdFrontmatter(filePath) {
|
|
284
1034
|
const content = fs.readFileSync(filePath, "utf8");
|
|
285
1035
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
286
1036
|
if (!match) throw new Error(`No frontmatter found in ${filePath}`);
|
|
287
|
-
return
|
|
1037
|
+
return yaml.load(match[1]);
|
|
288
1038
|
}
|
|
289
1039
|
function loadPack(packDir) {
|
|
290
1040
|
const skillMdPath = `${packDir}/SKILL.md`;
|
|
@@ -294,7 +1044,7 @@ function loadPack(packDir) {
|
|
|
294
1044
|
if (fs.existsSync(skillMdPath)) {
|
|
295
1045
|
rawManifest = parseSkillMdFrontmatter(skillMdPath);
|
|
296
1046
|
} else if (fs.existsSync(manifestYamlPath)) {
|
|
297
|
-
rawManifest =
|
|
1047
|
+
rawManifest = yaml.load(fs.readFileSync(manifestYamlPath, "utf8"));
|
|
298
1048
|
} else {
|
|
299
1049
|
throw new Error(`No SKILL.md or manifest.yaml found in ${packDir}`);
|
|
300
1050
|
}
|
|
@@ -326,6 +1076,165 @@ function generateEngramId(existing) {
|
|
|
326
1076
|
return `${prefix}${String(next).padStart(3, "0")}`;
|
|
327
1077
|
}
|
|
328
1078
|
|
|
1079
|
+
// src/storage-indexed.ts
|
|
1080
|
+
var Database = null;
|
|
1081
|
+
function getDatabase() {
|
|
1082
|
+
if (!Database) {
|
|
1083
|
+
try {
|
|
1084
|
+
Database = require_lib();
|
|
1085
|
+
} catch {
|
|
1086
|
+
throw new Error(
|
|
1087
|
+
"better-sqlite3 is required for index: true. Install it with: npm install better-sqlite3"
|
|
1088
|
+
);
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
return Database;
|
|
1092
|
+
}
|
|
1093
|
+
var IndexedStorage = class {
|
|
1094
|
+
dbPath;
|
|
1095
|
+
engramsPath;
|
|
1096
|
+
db = null;
|
|
1097
|
+
constructor(engramsPath, dbPath) {
|
|
1098
|
+
this.engramsPath = engramsPath;
|
|
1099
|
+
this.dbPath = dbPath;
|
|
1100
|
+
}
|
|
1101
|
+
getDb() {
|
|
1102
|
+
if (!this.db) {
|
|
1103
|
+
const DB = getDatabase();
|
|
1104
|
+
this.db = new DB(this.dbPath);
|
|
1105
|
+
this.db.pragma("journal_mode = WAL");
|
|
1106
|
+
this.db.exec(`
|
|
1107
|
+
CREATE TABLE IF NOT EXISTS engrams (
|
|
1108
|
+
id TEXT PRIMARY KEY,
|
|
1109
|
+
status TEXT NOT NULL,
|
|
1110
|
+
scope TEXT NOT NULL,
|
|
1111
|
+
domain TEXT,
|
|
1112
|
+
last_accessed TEXT,
|
|
1113
|
+
data TEXT NOT NULL
|
|
1114
|
+
);
|
|
1115
|
+
CREATE INDEX IF NOT EXISTS idx_status ON engrams(status);
|
|
1116
|
+
CREATE INDEX IF NOT EXISTS idx_scope ON engrams(scope);
|
|
1117
|
+
CREATE INDEX IF NOT EXISTS idx_domain ON engrams(domain);
|
|
1118
|
+
`);
|
|
1119
|
+
}
|
|
1120
|
+
return this.db;
|
|
1121
|
+
}
|
|
1122
|
+
/** Load all engrams from SQLite index. Auto-rebuilds if db missing. */
|
|
1123
|
+
loadAll() {
|
|
1124
|
+
if (!existsSync3(this.dbPath)) {
|
|
1125
|
+
this.reindex();
|
|
1126
|
+
}
|
|
1127
|
+
const db = this.getDb();
|
|
1128
|
+
const rows = db.prepare("SELECT data FROM engrams").all();
|
|
1129
|
+
return rows.map((r) => JSON.parse(r.data));
|
|
1130
|
+
}
|
|
1131
|
+
/** Load engrams with SQL-level filtering. */
|
|
1132
|
+
loadFiltered(filter) {
|
|
1133
|
+
if (!existsSync3(this.dbPath)) {
|
|
1134
|
+
this.reindex();
|
|
1135
|
+
}
|
|
1136
|
+
const db = this.getDb();
|
|
1137
|
+
const conditions = [];
|
|
1138
|
+
const params = [];
|
|
1139
|
+
if (filter.status) {
|
|
1140
|
+
conditions.push("status = ?");
|
|
1141
|
+
params.push(filter.status);
|
|
1142
|
+
}
|
|
1143
|
+
if (filter.scope) {
|
|
1144
|
+
conditions.push("(scope = 'global' OR scope = ? OR scope LIKE ? || '%')");
|
|
1145
|
+
params.push(filter.scope, filter.scope);
|
|
1146
|
+
}
|
|
1147
|
+
if (filter.domain) {
|
|
1148
|
+
conditions.push("domain LIKE ? || '%'");
|
|
1149
|
+
params.push(filter.domain);
|
|
1150
|
+
}
|
|
1151
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
1152
|
+
const rows = db.prepare(`SELECT data FROM engrams ${where}`).all(...params);
|
|
1153
|
+
return rows.map((r) => JSON.parse(r.data));
|
|
1154
|
+
}
|
|
1155
|
+
/** Count engrams with optional status filter. */
|
|
1156
|
+
count(filter) {
|
|
1157
|
+
if (!existsSync3(this.dbPath)) {
|
|
1158
|
+
this.reindex();
|
|
1159
|
+
}
|
|
1160
|
+
const db = this.getDb();
|
|
1161
|
+
if (filter?.status) {
|
|
1162
|
+
return db.prepare("SELECT COUNT(*) as c FROM engrams WHERE status = ?").get(filter.status).c;
|
|
1163
|
+
}
|
|
1164
|
+
return db.prepare("SELECT COUNT(*) as c FROM engrams").get().c;
|
|
1165
|
+
}
|
|
1166
|
+
/** Sync SQLite index from YAML source of truth. */
|
|
1167
|
+
syncFromYaml() {
|
|
1168
|
+
const engrams = loadEngrams(this.engramsPath);
|
|
1169
|
+
const db = this.getDb();
|
|
1170
|
+
const upsert = db.prepare(`
|
|
1171
|
+
INSERT OR REPLACE INTO engrams (id, status, scope, domain, last_accessed, data)
|
|
1172
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
1173
|
+
`);
|
|
1174
|
+
const deleteStmt = db.prepare("DELETE FROM engrams WHERE id = ?");
|
|
1175
|
+
const yamlIds = new Set(engrams.map((e) => e.id));
|
|
1176
|
+
const dbIds = new Set(
|
|
1177
|
+
db.prepare("SELECT id FROM engrams").all().map((r) => r.id)
|
|
1178
|
+
);
|
|
1179
|
+
const tx = db.transaction(() => {
|
|
1180
|
+
for (const e of engrams) {
|
|
1181
|
+
upsert.run(e.id, e.status, e.scope, e.domain ?? null, e.activation.last_accessed, JSON.stringify(e));
|
|
1182
|
+
}
|
|
1183
|
+
for (const id of dbIds) {
|
|
1184
|
+
if (!yamlIds.has(id)) deleteStmt.run(id);
|
|
1185
|
+
}
|
|
1186
|
+
});
|
|
1187
|
+
tx();
|
|
1188
|
+
}
|
|
1189
|
+
/** Drop and rebuild the entire index from YAML. */
|
|
1190
|
+
reindex() {
|
|
1191
|
+
this.close();
|
|
1192
|
+
const db = this.getDb();
|
|
1193
|
+
db.exec("DELETE FROM engrams");
|
|
1194
|
+
this.syncFromYaml();
|
|
1195
|
+
}
|
|
1196
|
+
/** Close the database connection. */
|
|
1197
|
+
close() {
|
|
1198
|
+
if (this.db) {
|
|
1199
|
+
this.db.close();
|
|
1200
|
+
this.db = null;
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
};
|
|
1204
|
+
|
|
1205
|
+
// src/config.ts
|
|
1206
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
|
|
1207
|
+
import yaml2 from "js-yaml";
|
|
1208
|
+
|
|
1209
|
+
// src/schemas/config.ts
|
|
1210
|
+
import { z as z3 } from "zod";
|
|
1211
|
+
var PlurConfigSchema = z3.object({
|
|
1212
|
+
auto_learn: z3.boolean().default(true),
|
|
1213
|
+
auto_capture: z3.boolean().default(true),
|
|
1214
|
+
injection_budget: z3.number().default(2e3),
|
|
1215
|
+
decay_enabled: z3.boolean().default(true),
|
|
1216
|
+
decay_threshold: z3.number().default(0.15),
|
|
1217
|
+
packs: z3.array(z3.string()).default([]),
|
|
1218
|
+
injection: z3.object({
|
|
1219
|
+
spread_cap: z3.number().default(3),
|
|
1220
|
+
spread_budget: z3.number().default(480),
|
|
1221
|
+
co_access: z3.boolean().default(true)
|
|
1222
|
+
}).default({}),
|
|
1223
|
+
allow_secrets: z3.boolean().default(false),
|
|
1224
|
+
index: z3.boolean().default(false)
|
|
1225
|
+
}).partial();
|
|
1226
|
+
|
|
1227
|
+
// src/config.ts
|
|
1228
|
+
function loadConfig(configPath) {
|
|
1229
|
+
if (!existsSync4(configPath)) return PlurConfigSchema.parse({});
|
|
1230
|
+
try {
|
|
1231
|
+
const raw = yaml2.load(readFileSync2(configPath, "utf8"));
|
|
1232
|
+
return PlurConfigSchema.parse(raw ?? {});
|
|
1233
|
+
} catch {
|
|
1234
|
+
return PlurConfigSchema.parse({});
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
|
|
329
1238
|
// src/decay.ts
|
|
330
1239
|
var DECAY_RATE = 0.05;
|
|
331
1240
|
var FLOOR = 0.05;
|
|
@@ -653,7 +1562,7 @@ function selectAndSpread(ctx, personalEngrams, packs, config, embeddingBoosts) {
|
|
|
653
1562
|
}
|
|
654
1563
|
|
|
655
1564
|
// src/episodes.ts
|
|
656
|
-
import { existsSync as
|
|
1565
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
|
|
657
1566
|
import yaml3 from "js-yaml";
|
|
658
1567
|
function generateEpisodeId() {
|
|
659
1568
|
const ts = Date.now();
|
|
@@ -688,7 +1597,7 @@ function queryTimeline(path2, query) {
|
|
|
688
1597
|
return episodes;
|
|
689
1598
|
}
|
|
690
1599
|
function loadEpisodes(path2) {
|
|
691
|
-
if (!
|
|
1600
|
+
if (!existsSync5(path2)) return [];
|
|
692
1601
|
try {
|
|
693
1602
|
const raw = yaml3.load(readFileSync3(path2, "utf8"));
|
|
694
1603
|
return Array.isArray(raw) ? raw : [];
|
|
@@ -1097,7 +2006,7 @@ async function computeSimilarityMatrix(templates) {
|
|
|
1097
2006
|
const n = templates.length;
|
|
1098
2007
|
const matrix = Array.from({ length: n }, () => Array(n).fill(0));
|
|
1099
2008
|
try {
|
|
1100
|
-
const { embed, cosineSimilarity } = await import("./embeddings-
|
|
2009
|
+
const { embed, cosineSimilarity } = await import("./embeddings-2IODIQAF.js");
|
|
1101
2010
|
const embeddings = [];
|
|
1102
2011
|
for (const t of templates) {
|
|
1103
2012
|
embeddings.push(await embed(t));
|
|
@@ -1832,9 +2741,13 @@ var INGEST_PATTERNS = [
|
|
|
1832
2741
|
var Plur = class {
|
|
1833
2742
|
paths;
|
|
1834
2743
|
config;
|
|
2744
|
+
indexedStorage = null;
|
|
1835
2745
|
constructor(options) {
|
|
1836
2746
|
this.paths = detectPlurStorage(options?.path);
|
|
1837
2747
|
this.config = loadConfig(this.paths.config);
|
|
2748
|
+
if (this.config.index) {
|
|
2749
|
+
this.indexedStorage = new IndexedStorage(this.paths.engrams, this.paths.db);
|
|
2750
|
+
}
|
|
1838
2751
|
}
|
|
1839
2752
|
/** Create engram, detect conflicts, save. Returns the created engram. */
|
|
1840
2753
|
learn(statement, context) {
|
|
@@ -1844,48 +2757,51 @@ var Plur = class {
|
|
|
1844
2757
|
throw new Error(`Secret detected in statement: ${secrets[0].pattern}. Use config.allow_secrets to override.`);
|
|
1845
2758
|
}
|
|
1846
2759
|
}
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
2760
|
+
return withLock(this.paths.engrams, () => {
|
|
2761
|
+
const engrams = loadEngrams(this.paths.engrams);
|
|
2762
|
+
const id = generateEngramId(engrams);
|
|
2763
|
+
const scope = context?.scope ?? "global";
|
|
2764
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2765
|
+
const conflictingEngrams = detectConflicts({ statement, scope }, engrams);
|
|
2766
|
+
const conflictIds = conflictingEngrams.map((e) => e.id);
|
|
2767
|
+
const engram = {
|
|
2768
|
+
id,
|
|
2769
|
+
version: 2,
|
|
2770
|
+
status: "active",
|
|
2771
|
+
consolidated: false,
|
|
2772
|
+
type: context?.type ?? "behavioral",
|
|
2773
|
+
scope,
|
|
2774
|
+
visibility: "private",
|
|
2775
|
+
statement,
|
|
2776
|
+
source: context?.source,
|
|
2777
|
+
domain: context?.domain,
|
|
2778
|
+
activation: {
|
|
2779
|
+
retrieval_strength: 0.7,
|
|
2780
|
+
storage_strength: 1,
|
|
2781
|
+
frequency: 0,
|
|
2782
|
+
last_accessed: now.slice(0, 10)
|
|
2783
|
+
},
|
|
2784
|
+
feedback_signals: { positive: 0, negative: 0, neutral: 0 },
|
|
2785
|
+
knowledge_anchors: [],
|
|
2786
|
+
associations: [],
|
|
2787
|
+
derivation_count: 1,
|
|
2788
|
+
tags: [],
|
|
2789
|
+
pack: null,
|
|
2790
|
+
abstract: null,
|
|
2791
|
+
derived_from: null,
|
|
2792
|
+
polarity: null,
|
|
2793
|
+
relations: conflictIds.length > 0 ? {
|
|
2794
|
+
broader: [],
|
|
2795
|
+
narrower: [],
|
|
2796
|
+
related: [],
|
|
2797
|
+
conflicts: conflictIds
|
|
2798
|
+
} : void 0
|
|
2799
|
+
};
|
|
2800
|
+
engrams.push(engram);
|
|
2801
|
+
saveEngrams(this.paths.engrams, engrams);
|
|
2802
|
+
this._syncIndex();
|
|
2803
|
+
return engram;
|
|
2804
|
+
});
|
|
1889
2805
|
}
|
|
1890
2806
|
/**
|
|
1891
2807
|
* Search engrams, filter by scope/domain/strength, reactivate accessed.
|
|
@@ -1939,75 +2855,89 @@ var Plur = class {
|
|
|
1939
2855
|
}
|
|
1940
2856
|
/** Filter engrams by scope/domain/strength (shared by both modes) */
|
|
1941
2857
|
_filterEngrams(options) {
|
|
1942
|
-
let engrams
|
|
1943
|
-
|
|
2858
|
+
let engrams;
|
|
2859
|
+
if (this.indexedStorage) {
|
|
2860
|
+
engrams = this.indexedStorage.loadFiltered({
|
|
2861
|
+
status: "active",
|
|
2862
|
+
scope: options?.scope,
|
|
2863
|
+
domain: options?.domain
|
|
2864
|
+
});
|
|
2865
|
+
} else {
|
|
2866
|
+
engrams = loadEngrams(this.paths.engrams);
|
|
2867
|
+
engrams = engrams.filter((e) => e.status === "active");
|
|
2868
|
+
if (options?.domain) {
|
|
2869
|
+
engrams = engrams.filter((e) => e.domain?.startsWith(options.domain));
|
|
2870
|
+
}
|
|
2871
|
+
if (options?.scope) {
|
|
2872
|
+
const scope = options.scope;
|
|
2873
|
+
engrams = engrams.filter(
|
|
2874
|
+
(e) => e.scope === "global" || e.scope === scope || e.scope.startsWith(scope)
|
|
2875
|
+
);
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
1944
2878
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
1945
2879
|
engrams = engrams.filter((e) => {
|
|
1946
2880
|
if (e.temporal?.valid_until && e.temporal.valid_until < today) return false;
|
|
1947
2881
|
if (e.temporal?.valid_from && e.temporal.valid_from > today) return false;
|
|
1948
2882
|
return true;
|
|
1949
2883
|
});
|
|
1950
|
-
if (options?.domain) {
|
|
1951
|
-
engrams = engrams.filter((e) => e.domain?.startsWith(options.domain));
|
|
1952
|
-
}
|
|
1953
2884
|
if (options?.min_strength !== void 0) {
|
|
1954
2885
|
engrams = engrams.filter((e) => e.activation.retrieval_strength >= options.min_strength);
|
|
1955
2886
|
}
|
|
1956
|
-
if (options?.scope) {
|
|
1957
|
-
const scope = options.scope;
|
|
1958
|
-
engrams = engrams.filter(
|
|
1959
|
-
(e) => e.scope === "global" || e.scope === scope || e.scope.startsWith(scope)
|
|
1960
|
-
);
|
|
1961
|
-
}
|
|
1962
2887
|
return engrams;
|
|
1963
2888
|
}
|
|
1964
2889
|
/** Reactivate accessed engrams and update co-access associations */
|
|
1965
2890
|
_reactivateResults(results) {
|
|
1966
2891
|
if (results.length === 0) return;
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
const
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
} else {
|
|
1995
|
-
const coAccessCount = source.associations.filter((a) => a.type === "co_accessed").length;
|
|
1996
|
-
if (coAccessCount < 5) {
|
|
1997
|
-
source.associations.push({
|
|
1998
|
-
target_type: "engram",
|
|
1999
|
-
target: targetId,
|
|
2000
|
-
type: "co_accessed",
|
|
2001
|
-
strength: 0.3,
|
|
2002
|
-
updated_at: today
|
|
2003
|
-
});
|
|
2892
|
+
withLock(this.paths.engrams, () => {
|
|
2893
|
+
const allEngrams = loadEngrams(this.paths.engrams);
|
|
2894
|
+
const resultIds = new Set(results.map((e) => e.id));
|
|
2895
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2896
|
+
let modified = false;
|
|
2897
|
+
for (const e of allEngrams) {
|
|
2898
|
+
if (resultIds.has(e.id)) {
|
|
2899
|
+
e.activation.retrieval_strength = reactivate(e.activation.retrieval_strength);
|
|
2900
|
+
e.activation.last_accessed = today;
|
|
2901
|
+
e.activation.frequency += 1;
|
|
2902
|
+
modified = true;
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
if (results.length >= 2 && this.config.injection?.co_access !== false) {
|
|
2906
|
+
const topHalf = results.slice(0, Math.max(2, Math.ceil(results.length / 2)));
|
|
2907
|
+
const topIds = topHalf.map((e) => e.id);
|
|
2908
|
+
for (const sourceId of topIds) {
|
|
2909
|
+
const source = allEngrams.find((e) => e.id === sourceId);
|
|
2910
|
+
if (!source) continue;
|
|
2911
|
+
for (const targetId of topIds) {
|
|
2912
|
+
if (targetId === sourceId) continue;
|
|
2913
|
+
const existing = source.associations.find(
|
|
2914
|
+
(a) => a.type === "co_accessed" && a.target === targetId
|
|
2915
|
+
);
|
|
2916
|
+
if (existing) {
|
|
2917
|
+
existing.strength = Math.min(0.95, existing.strength + 0.05);
|
|
2918
|
+
existing.updated_at = today;
|
|
2004
2919
|
modified = true;
|
|
2920
|
+
} else {
|
|
2921
|
+
const coAccessCount = source.associations.filter((a) => a.type === "co_accessed").length;
|
|
2922
|
+
if (coAccessCount < 5) {
|
|
2923
|
+
source.associations.push({
|
|
2924
|
+
target_type: "engram",
|
|
2925
|
+
target: targetId,
|
|
2926
|
+
type: "co_accessed",
|
|
2927
|
+
strength: 0.3,
|
|
2928
|
+
updated_at: today
|
|
2929
|
+
});
|
|
2930
|
+
modified = true;
|
|
2931
|
+
}
|
|
2005
2932
|
}
|
|
2006
2933
|
}
|
|
2007
2934
|
}
|
|
2008
2935
|
}
|
|
2009
|
-
|
|
2010
|
-
|
|
2936
|
+
if (modified) {
|
|
2937
|
+
saveEngrams(this.paths.engrams, allEngrams);
|
|
2938
|
+
this._syncIndex();
|
|
2939
|
+
}
|
|
2940
|
+
});
|
|
2011
2941
|
}
|
|
2012
2942
|
/** Scored injection within token budget (BM25 only). Returns formatted strings. */
|
|
2013
2943
|
inject(task, options) {
|
|
@@ -2066,56 +2996,96 @@ var Plur = class {
|
|
|
2066
2996
|
}
|
|
2067
2997
|
/** Update feedback_signals and adjust retrieval_strength. */
|
|
2068
2998
|
feedback(id, signal) {
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
engram.feedback_signals
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2999
|
+
withLock(this.paths.engrams, () => {
|
|
3000
|
+
const engrams = loadEngrams(this.paths.engrams);
|
|
3001
|
+
const engram = engrams.find((e) => e.id === id);
|
|
3002
|
+
if (!engram) throw new Error(`Engram not found: ${id}`);
|
|
3003
|
+
if (!engram.feedback_signals) {
|
|
3004
|
+
engram.feedback_signals = { positive: 0, negative: 0, neutral: 0 };
|
|
3005
|
+
}
|
|
3006
|
+
engram.feedback_signals[signal] += 1;
|
|
3007
|
+
if (signal === "positive") {
|
|
3008
|
+
engram.activation.retrieval_strength = Math.min(1, engram.activation.retrieval_strength + 0.05);
|
|
3009
|
+
} else if (signal === "negative") {
|
|
3010
|
+
engram.activation.retrieval_strength = Math.max(0, engram.activation.retrieval_strength - 0.1);
|
|
3011
|
+
}
|
|
3012
|
+
saveEngrams(this.paths.engrams, engrams);
|
|
3013
|
+
this._syncIndex();
|
|
3014
|
+
});
|
|
2082
3015
|
}
|
|
2083
3016
|
/** Save extracted meta-engrams to the engram store. Skips IDs that already exist. */
|
|
2084
3017
|
saveMetaEngrams(metas) {
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
3018
|
+
return withLock(this.paths.engrams, () => {
|
|
3019
|
+
const engrams = loadEngrams(this.paths.engrams);
|
|
3020
|
+
const existingIds = new Set(engrams.map((e) => e.id));
|
|
3021
|
+
let saved = 0;
|
|
3022
|
+
let skipped = 0;
|
|
3023
|
+
for (const meta of metas) {
|
|
3024
|
+
if (existingIds.has(meta.id)) {
|
|
3025
|
+
skipped++;
|
|
3026
|
+
} else {
|
|
3027
|
+
engrams.push(meta);
|
|
3028
|
+
saved++;
|
|
3029
|
+
}
|
|
2095
3030
|
}
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
3031
|
+
if (saved > 0) {
|
|
3032
|
+
saveEngrams(this.paths.engrams, engrams);
|
|
3033
|
+
this._syncIndex();
|
|
3034
|
+
}
|
|
3035
|
+
return { saved, skipped };
|
|
3036
|
+
});
|
|
2099
3037
|
}
|
|
2100
3038
|
/** Update an existing engram in the store by ID. Returns true if found and updated. */
|
|
2101
3039
|
updateEngram(updated) {
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
3040
|
+
return withLock(this.paths.engrams, () => {
|
|
3041
|
+
const engrams = loadEngrams(this.paths.engrams);
|
|
3042
|
+
const idx = engrams.findIndex((e) => e.id === updated.id);
|
|
3043
|
+
if (idx === -1) return false;
|
|
3044
|
+
engrams[idx] = updated;
|
|
3045
|
+
saveEngrams(this.paths.engrams, engrams);
|
|
3046
|
+
this._syncIndex();
|
|
3047
|
+
return true;
|
|
3048
|
+
});
|
|
2108
3049
|
}
|
|
2109
3050
|
/** Set engram status to 'retired'. */
|
|
2110
3051
|
forget(id, reason) {
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
engram.rationale
|
|
3052
|
+
withLock(this.paths.engrams, () => {
|
|
3053
|
+
const engrams = loadEngrams(this.paths.engrams);
|
|
3054
|
+
const engram = engrams.find((e) => e.id === id);
|
|
3055
|
+
if (!engram) throw new Error(`Engram not found: ${id}`);
|
|
3056
|
+
engram.status = "retired";
|
|
3057
|
+
if (reason && !engram.rationale) {
|
|
3058
|
+
engram.rationale = `Retired: ${reason}`;
|
|
3059
|
+
}
|
|
3060
|
+
saveEngrams(this.paths.engrams, engrams);
|
|
3061
|
+
this._syncIndex();
|
|
3062
|
+
});
|
|
3063
|
+
}
|
|
3064
|
+
/** Remove retired engrams from storage. Returns count of removed and remaining. */
|
|
3065
|
+
compact() {
|
|
3066
|
+
return withLock(this.paths.engrams, () => {
|
|
3067
|
+
const engrams = loadEngrams(this.paths.engrams);
|
|
3068
|
+
const active = engrams.filter((e) => e.status !== "retired");
|
|
3069
|
+
const removed = engrams.length - active.length;
|
|
3070
|
+
if (removed > 0) {
|
|
3071
|
+
saveEngrams(this.paths.engrams, active);
|
|
3072
|
+
this._syncIndex();
|
|
3073
|
+
}
|
|
3074
|
+
return { removed, remaining: active.length };
|
|
3075
|
+
});
|
|
3076
|
+
}
|
|
3077
|
+
/** Rebuild SQLite index from YAML source of truth. Only works when index: true. */
|
|
3078
|
+
reindex() {
|
|
3079
|
+
if (!this.indexedStorage) {
|
|
3080
|
+
this.indexedStorage = new IndexedStorage(this.paths.engrams, this.paths.db);
|
|
3081
|
+
}
|
|
3082
|
+
this.indexedStorage.reindex();
|
|
3083
|
+
}
|
|
3084
|
+
/** Sync SQLite index after YAML write (no-op if index disabled) */
|
|
3085
|
+
_syncIndex() {
|
|
3086
|
+
if (this.indexedStorage) {
|
|
3087
|
+
this.indexedStorage.syncFromYaml();
|
|
2117
3088
|
}
|
|
2118
|
-
saveEngrams(this.paths.engrams, engrams);
|
|
2119
3089
|
}
|
|
2120
3090
|
/** Capture an episodic memory. */
|
|
2121
3091
|
capture(summary, context) {
|
|
@@ -2196,6 +3166,7 @@ export {
|
|
|
2196
3166
|
EvidenceEntrySchema,
|
|
2197
3167
|
FalsificationSchema,
|
|
2198
3168
|
HierarchyPositionSchema,
|
|
3169
|
+
IndexedStorage,
|
|
2199
3170
|
MetaConfidenceSchema,
|
|
2200
3171
|
MetaFieldSchema,
|
|
2201
3172
|
PLATITUDE_PATTERNS,
|