@equationalapplications/expo-llm-wiki 0.0.0-development → 2.1.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
@@ -1,5 +1,10 @@
1
1
  # expo-llm-wiki
2
2
 
3
+ [![GitHub Tag](https://img.shields.io/github/v/tag/equationalapplications/expo-llm-wiki?label=github%20tag)](https://github.com/equationalapplications/expo-llm-wiki/tags)
4
+ [![npm version](https://img.shields.io/npm/v/%40equationalapplications%2Fexpo-llm-wiki?label=npm)](https://www.npmjs.com/package/@equationalapplications/expo-llm-wiki)
5
+ [![npm downloads](https://img.shields.io/npm/dm/%40equationalapplications%2Fexpo-llm-wiki?label=downloads)](https://www.npmjs.com/package/@equationalapplications/expo-llm-wiki)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
7
+
3
8
  Offline-first, SQLite-backed memory for LLM apps built with Expo. Handles FTS5 search, episodic event logging, background fact extraction, and memory healing — bring your own LLM.
4
9
 
5
10
  ## Key Principles
@@ -8,6 +13,7 @@ Offline-first, SQLite-backed memory for LLM apps built with Expo. Handles FTS5 s
8
13
  - **Namespace Safe:** All tables are prefixed (default: `llm_wiki_`) — no collisions with your existing database.
9
14
  - **Multi-Entity:** Multiple independent "brains" in one database via `entityId`.
10
15
  - **Offline First:** Reads are fully local via SQLite FTS5, typically under 50ms.
16
+ - **Morphological Matching:** Porter stemming enables recall across word forms — queries for `running` match facts about `run`, `runs`, etc., without manual synonym configuration.
11
17
  - **Full Unicode Support:** UTF-8 and UTF-16 (including surrogate pairs for emoji) are fully supported. Chunks are split safely at sentence boundaries; surrogate pairs are never fragmented.
12
18
 
13
19
  ## How It Works
@@ -89,6 +95,8 @@ const wiki = createWiki(db, {
89
95
  maxFtsResults: 10, // optional, default: 10
90
96
  autoLibrarianThreshold: 20, // optional, default: 20
91
97
  maxChunkLength: 6000, // optional, default: 6000 (char count, not bytes)
98
+ chunkOverlap: 400, // optional, default: 400 (overlap between chunks in characters)
99
+ chunkConcurrency: 1, // optional, default: 1 (parallel LLM calls per ingestDocument)
92
100
  },
93
101
  });
94
102
 
@@ -135,7 +143,9 @@ const result = await wiki.ingestDocument('entity-123', {
135
143
  sourceRef: 'preferences.md', // stable identifier
136
144
  sourceHash: sha256(content), // for change detection
137
145
  documentChunk: content,
138
- maxChunkLength: 6000, // optional, character count
146
+ maxChunkLength: 12000, // optional, character count
147
+ chunkOverlap: 400, // optional, overlap in characters
148
+ chunkConcurrency: 1, // optional, parallel LLM calls per ingest (default: 1)
139
149
  });
140
150
  // result: { truncated: boolean; chunks: number }
141
151
  // truncated: true if at least one hard-split was required (no sentence boundary)
@@ -257,3 +267,7 @@ All mutation hooks follow the same pattern (`TResult` is specific per hook):
257
267
  error: Error | null; // cleared on the next execute call
258
268
  }
259
269
  ```
270
+
271
+ ---
272
+
273
+ Made with ❤️ by Equational Applications LLC. [https://equationalapplications.com/](https://equationalapplications.com/)
@@ -9,6 +9,17 @@ interface WikiConfig {
9
9
  orphanAfterDays?: number | null;
10
10
  staleInferredAfterDays?: number | null;
11
11
  maxChunkLength?: number;
12
+ chunkOverlap?: number;
13
+ chunkConcurrency?: number;
14
+ /**
15
+ * Static caller-supplied synonym expansions applied at query time.
16
+ * Keys must match the same normalization pipeline used by query formatting:
17
+ * the query is lowercased, stripped to `[a-z0-9 ]`, split into tokens, and
18
+ * only tokens with length >= 3 are considered for synonym lookup.
19
+ * Values are appended to the FTS5 query token list (multi-word values are
20
+ * split into tokens), then deduped and sliced to 12.
21
+ */
22
+ synonymMap?: Record<string, string[]>;
12
23
  }
13
24
  interface WikiFact {
14
25
  id: string;
@@ -79,22 +90,54 @@ interface MemoryBundle {
79
90
  tasks: WikiTask[];
80
91
  events: WikiEvent[];
81
92
  }
93
+ interface MemoryDump {
94
+ generatedAt: number;
95
+ entities: Record<string, MemoryBundle>;
96
+ }
97
+ interface FormattedMemoryDump {
98
+ manifest: string;
99
+ files: Array<{
100
+ name: string;
101
+ content: string;
102
+ }>;
103
+ }
104
+ interface EntityStatus {
105
+ ingesting: boolean;
106
+ librarian: boolean;
107
+ heal: boolean;
108
+ }
109
+ declare class WikiBusyError extends Error {
110
+ readonly operation: 'ingest' | 'librarian' | 'heal';
111
+ readonly entityId: string;
112
+ constructor(operation: 'ingest' | 'librarian' | 'heal', entityId: string);
113
+ }
82
114
 
83
115
  declare class WikiMemory {
84
116
  private db;
85
117
  private prefix;
86
118
  private options;
87
119
  private activeMaintenanceJobs;
120
+ private activeIngestJobs;
121
+ private _librarianKey;
122
+ private _healKey;
123
+ private _warnCrossEntityCollision;
88
124
  constructor(db: SQLite.SQLiteDatabase, options: WikiOptions);
89
125
  setup(): Promise<void>;
90
126
  private formatSearchQuery;
91
127
  read(entityId: string, query: string): Promise<MemoryBundle>;
128
+ getMemoryBundle(entityId: string): Promise<MemoryBundle>;
92
129
  write(entityId: string, event: Omit<WikiEvent, 'id' | 'entity_id' | 'created_at'>): Promise<void>;
93
130
  private runLibrarianThenMaybeHeal;
94
131
  private _doRunLibrarian;
95
132
  private _doRunHeal;
96
133
  runLibrarian(entityId: string): Promise<void>;
97
134
  runHeal(entityId: string): Promise<void>;
135
+ getEntityStatus(entityId: string): EntityStatus;
136
+ private _getFullBundle;
137
+ exportDump(entityIds?: string[]): Promise<MemoryDump>;
138
+ importDump(dump: MemoryDump, opts?: {
139
+ merge?: boolean;
140
+ }): Promise<void>;
98
141
  forget(entityId: string, params: {
99
142
  entryId?: string;
100
143
  taskId?: string;
@@ -112,10 +155,12 @@ declare class WikiMemory {
112
155
  sourceHash: string;
113
156
  documentChunk: string;
114
157
  maxChunkLength?: number;
158
+ chunkOverlap?: number;
159
+ chunkConcurrency?: number;
115
160
  }): Promise<{
116
161
  truncated: boolean;
117
162
  chunks: number;
118
163
  }>;
119
164
  }
120
165
 
121
- export { type ExtractedFact as E, type LLMProvider as L, type MemoryBundle as M, type WikiOptions as W, WikiMemory as a, type ExtractedTask as b, type WikiCheckpoint as c, type WikiConfig as d, type WikiEvent as e, type WikiFact as f, type WikiTask as g };
166
+ export { type EntityStatus as E, type FormattedMemoryDump as F, type LLMProvider as L, type MemoryDump as M, type WikiOptions as W, WikiMemory as a, type ExtractedFact as b, type ExtractedTask as c, type MemoryBundle as d, WikiBusyError as e, type WikiCheckpoint as f, type WikiConfig as g, type WikiEvent as h, type WikiFact as i, type WikiTask as j };
@@ -9,6 +9,17 @@ interface WikiConfig {
9
9
  orphanAfterDays?: number | null;
10
10
  staleInferredAfterDays?: number | null;
11
11
  maxChunkLength?: number;
12
+ chunkOverlap?: number;
13
+ chunkConcurrency?: number;
14
+ /**
15
+ * Static caller-supplied synonym expansions applied at query time.
16
+ * Keys must match the same normalization pipeline used by query formatting:
17
+ * the query is lowercased, stripped to `[a-z0-9 ]`, split into tokens, and
18
+ * only tokens with length >= 3 are considered for synonym lookup.
19
+ * Values are appended to the FTS5 query token list (multi-word values are
20
+ * split into tokens), then deduped and sliced to 12.
21
+ */
22
+ synonymMap?: Record<string, string[]>;
12
23
  }
13
24
  interface WikiFact {
14
25
  id: string;
@@ -79,22 +90,54 @@ interface MemoryBundle {
79
90
  tasks: WikiTask[];
80
91
  events: WikiEvent[];
81
92
  }
93
+ interface MemoryDump {
94
+ generatedAt: number;
95
+ entities: Record<string, MemoryBundle>;
96
+ }
97
+ interface FormattedMemoryDump {
98
+ manifest: string;
99
+ files: Array<{
100
+ name: string;
101
+ content: string;
102
+ }>;
103
+ }
104
+ interface EntityStatus {
105
+ ingesting: boolean;
106
+ librarian: boolean;
107
+ heal: boolean;
108
+ }
109
+ declare class WikiBusyError extends Error {
110
+ readonly operation: 'ingest' | 'librarian' | 'heal';
111
+ readonly entityId: string;
112
+ constructor(operation: 'ingest' | 'librarian' | 'heal', entityId: string);
113
+ }
82
114
 
83
115
  declare class WikiMemory {
84
116
  private db;
85
117
  private prefix;
86
118
  private options;
87
119
  private activeMaintenanceJobs;
120
+ private activeIngestJobs;
121
+ private _librarianKey;
122
+ private _healKey;
123
+ private _warnCrossEntityCollision;
88
124
  constructor(db: SQLite.SQLiteDatabase, options: WikiOptions);
89
125
  setup(): Promise<void>;
90
126
  private formatSearchQuery;
91
127
  read(entityId: string, query: string): Promise<MemoryBundle>;
128
+ getMemoryBundle(entityId: string): Promise<MemoryBundle>;
92
129
  write(entityId: string, event: Omit<WikiEvent, 'id' | 'entity_id' | 'created_at'>): Promise<void>;
93
130
  private runLibrarianThenMaybeHeal;
94
131
  private _doRunLibrarian;
95
132
  private _doRunHeal;
96
133
  runLibrarian(entityId: string): Promise<void>;
97
134
  runHeal(entityId: string): Promise<void>;
135
+ getEntityStatus(entityId: string): EntityStatus;
136
+ private _getFullBundle;
137
+ exportDump(entityIds?: string[]): Promise<MemoryDump>;
138
+ importDump(dump: MemoryDump, opts?: {
139
+ merge?: boolean;
140
+ }): Promise<void>;
98
141
  forget(entityId: string, params: {
99
142
  entryId?: string;
100
143
  taskId?: string;
@@ -112,10 +155,12 @@ declare class WikiMemory {
112
155
  sourceHash: string;
113
156
  documentChunk: string;
114
157
  maxChunkLength?: number;
158
+ chunkOverlap?: number;
159
+ chunkConcurrency?: number;
115
160
  }): Promise<{
116
161
  truncated: boolean;
117
162
  chunks: number;
118
163
  }>;
119
164
  }
120
165
 
121
- export { type ExtractedFact as E, type LLMProvider as L, type MemoryBundle as M, type WikiOptions as W, WikiMemory as a, type ExtractedTask as b, type WikiCheckpoint as c, type WikiConfig as d, type WikiEvent as e, type WikiFact as f, type WikiTask as g };
166
+ export { type EntityStatus as E, type FormattedMemoryDump as F, type LLMProvider as L, type MemoryDump as M, type WikiOptions as W, WikiMemory as a, type ExtractedFact as b, type ExtractedTask as c, type MemoryBundle as d, WikiBusyError as e, type WikiCheckpoint as f, type WikiConfig as g, type WikiEvent as h, type WikiFact as i, type WikiTask as j };
package/dist/index.d.mts CHANGED
@@ -1,7 +1,9 @@
1
1
  import * as SQLite from 'expo-sqlite';
2
- import { W as WikiOptions, a as WikiMemory } from './WikiMemory-BI2Aizwv.mjs';
3
- export { E as ExtractedFact, b as ExtractedTask, L as LLMProvider, M as MemoryBundle, c as WikiCheckpoint, d as WikiConfig, e as WikiEvent, f as WikiFact, g as WikiTask } from './WikiMemory-BI2Aizwv.mjs';
2
+ import { M as MemoryDump, F as FormattedMemoryDump, W as WikiOptions, a as WikiMemory } from './WikiMemory-BDVn-TJf.mjs';
3
+ export { E as EntityStatus, b as ExtractedFact, c as ExtractedTask, L as LLMProvider, d as MemoryBundle, e as WikiBusyError, f as WikiCheckpoint, g as WikiConfig, h as WikiEvent, i as WikiFact, j as WikiTask } from './WikiMemory-BDVn-TJf.mjs';
4
+
5
+ declare function formatMemoryDump(dump: MemoryDump): FormattedMemoryDump;
4
6
 
5
7
  declare function createWiki(db: SQLite.SQLiteDatabase, options: WikiOptions): WikiMemory;
6
8
 
7
- export { WikiMemory, WikiOptions, createWiki };
9
+ export { FormattedMemoryDump, MemoryDump, WikiMemory, WikiOptions, createWiki, formatMemoryDump };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import * as SQLite from 'expo-sqlite';
2
- import { W as WikiOptions, a as WikiMemory } from './WikiMemory-BI2Aizwv.js';
3
- export { E as ExtractedFact, b as ExtractedTask, L as LLMProvider, M as MemoryBundle, c as WikiCheckpoint, d as WikiConfig, e as WikiEvent, f as WikiFact, g as WikiTask } from './WikiMemory-BI2Aizwv.js';
2
+ import { M as MemoryDump, F as FormattedMemoryDump, W as WikiOptions, a as WikiMemory } from './WikiMemory-BDVn-TJf.js';
3
+ export { E as EntityStatus, b as ExtractedFact, c as ExtractedTask, L as LLMProvider, d as MemoryBundle, e as WikiBusyError, f as WikiCheckpoint, g as WikiConfig, h as WikiEvent, i as WikiFact, j as WikiTask } from './WikiMemory-BDVn-TJf.js';
4
+
5
+ declare function formatMemoryDump(dump: MemoryDump): FormattedMemoryDump;
4
6
 
5
7
  declare function createWiki(db: SQLite.SQLiteDatabase, options: WikiOptions): WikiMemory;
6
8
 
7
- export { WikiMemory, WikiOptions, createWiki };
9
+ export { FormattedMemoryDump, MemoryDump, WikiMemory, WikiOptions, createWiki, formatMemoryDump };