@monlite/core 0.8.0 → 0.10.0

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/README.md CHANGED
@@ -525,6 +525,32 @@ db.driverName; // "better-sqlite3" | "node:sqlite"
525
525
 
526
526
  ---
527
527
 
528
+ ## Plugins
529
+
530
+ `@monlite/core` stays lean; heavier or optional capabilities are opt-in plugins
531
+ passed to `createDb`:
532
+
533
+ ```ts
534
+ import { createDb } from "@monlite/core";
535
+ import { fts } from "@monlite/fts";
536
+
537
+ const db = createDb("./app.db", {
538
+ plugins: [fts({ posts: ["title", "body"] })],
539
+ });
540
+
541
+ await db.collection("posts").search("hello world"); // full-text search
542
+ ```
543
+
544
+ | Plugin | Adds |
545
+ |---|---|
546
+ | [`@monlite/fts`](https://www.npmjs.com/package/@monlite/fts) | Full-text search (SQLite FTS5) via `collection.search()` |
547
+ | [`@monlite/vector`](https://www.npmjs.com/package/@monlite/vector) | Vector / semantic search (sqlite-vec) via `collection.findSimilar()` — RAG, agent memory |
548
+
549
+ Write your own against the `MonlitePlugin` interface (`init` / `afterWrite` /
550
+ `collectionMethods` hooks).
551
+
552
+ ---
553
+
528
554
  ## Drivers & zero dependencies
529
555
 
530
556
  monlite talks to SQLite through a tiny driver adapter, so it runs on two
package/dist/index.cjs CHANGED
@@ -952,9 +952,11 @@ var Collection = class {
952
952
  ).run(...values);
953
953
  this.afterWrite([id]);
954
954
  }
955
- /** @internal Notify reactivity watchers that documents changed. */
955
+ /** @internal Notify reactivity watchers and plugins that documents changed. */
956
956
  afterWrite(ids) {
957
+ if (ids.length === 0) return;
957
958
  this.mon.reactor.emit(this.name, ids);
959
+ this.mon.firePluginAfterWrite(this.name, ids);
958
960
  }
959
961
  /* ----------------------------- create ----------------------------- */
960
962
  async create(args) {
@@ -1371,8 +1373,10 @@ var NodeSqliteDriver = class {
1371
1373
  this.verbose = options.verbose;
1372
1374
  const { DatabaseSync } = nodeSqlite;
1373
1375
  this.raw = new DatabaseSync(filename, {
1374
- readOnly: options.readonly ?? false
1376
+ readOnly: options.readonly ?? false,
1377
+ ...options.allowExtensions ? { allowExtension: true } : {}
1375
1378
  });
1379
+ if (options.allowExtensions) this.raw.enableLoadExtension(true);
1376
1380
  this.raw.exec(`PRAGMA busy_timeout = ${options.busyTimeout ?? 5e3}`);
1377
1381
  if (!options.readonly && (options.wal ?? true)) {
1378
1382
  this.raw.exec("PRAGMA journal_mode = WAL");
@@ -1888,6 +1892,7 @@ var Monlite = class {
1888
1892
  /** @internal Sync metadata store; present only when `{ sync: true }`. */
1889
1893
  $sync;
1890
1894
  collections = /* @__PURE__ */ new Map();
1895
+ plugins;
1891
1896
  closed = false;
1892
1897
  constructor(filename, options = {}) {
1893
1898
  this.driver = createDriver(filename, {
@@ -1895,6 +1900,7 @@ var Monlite = class {
1895
1900
  readonly: options.readonly,
1896
1901
  wal: options.wal,
1897
1902
  busyTimeout: options.busyTimeout,
1903
+ allowExtensions: options.allowExtensions,
1898
1904
  verbose: options.verbose
1899
1905
  });
1900
1906
  this.autoIndexer = new AutoIndexer(
@@ -1905,6 +1911,15 @@ var Monlite = class {
1905
1911
  if (options.sync) {
1906
1912
  this.$sync = new SyncStore(this.driver, options.nodeId, this);
1907
1913
  }
1914
+ this.plugins = options.plugins ?? [];
1915
+ for (const plugin of this.plugins) plugin.init?.(this);
1916
+ }
1917
+ /** @internal Notify plugins that documents changed (post-commit). */
1918
+ firePluginAfterWrite(collection, ids) {
1919
+ if (this.plugins.length === 0 || ids.length === 0) return;
1920
+ for (const plugin of this.plugins) {
1921
+ plugin.afterWrite?.(this, { collection, ids });
1922
+ }
1908
1923
  }
1909
1924
  /** Stable node id for LWW tie-breaking (only when sync is enabled). */
1910
1925
  get nodeId() {
@@ -1930,6 +1945,13 @@ var Monlite = class {
1930
1945
  if (!col) {
1931
1946
  col = new Collection(this, name, options);
1932
1947
  this.collections.set(name, col);
1948
+ for (const plugin of this.plugins) {
1949
+ for (const [method, impl] of Object.entries(
1950
+ plugin.collectionMethods ?? {}
1951
+ )) {
1952
+ col[method] = (...args) => impl(col, ...args);
1953
+ }
1954
+ }
1933
1955
  } else if (options?.schema) {
1934
1956
  const requested = Object.keys(options.schema);
1935
1957
  const existing = new Set(col.columnNames);