@tangle-network/agent-app 0.1.10 → 0.1.11

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.
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Swappable database provider — the seam that decouples the agent's persistence
3
+ * from any one driver.
4
+ *
5
+ * The agent core (and the app's server modules) import a single `db` and use it
6
+ * directly. That `db` is a lazy proxy: it forwards to whatever database instance
7
+ * the runtime injects via {@link DatabaseProvider.setDatabase}. So the SAME core
8
+ * runs on:
9
+ * - Cloudflare D1 (`setDatabase(drizzle(d1, schema))`) — prod
10
+ * - SQLite / miniflare (`setDatabase(drizzle(betterSqlite, schema))`) — eval / the portable inner shell
11
+ * - libsql / Turso, Postgres (`setDatabase(drizzle(client, schema))`) — a future hosted DB
12
+ *
13
+ * Adding a new database is one adapter (a drizzle instance over a new driver) +
14
+ * a `setDatabase` call. None of the modules importing `db` change. Substrate-
15
+ * free and driver-agnostic: this module knows nothing about D1, drizzle, or any
16
+ * schema — it only forwards property access to the injected instance.
17
+ */
18
+ interface DatabaseProvider<DB> {
19
+ /** The injected database, as a lazy proxy. Throws (with `notReadyMessage`)
20
+ * on any access before {@link setDatabase} is called. */
21
+ readonly db: DB;
22
+ /** Inject the active database instance (any driver's client). */
23
+ setDatabase(database: DB): void;
24
+ /** True once a database has been injected. */
25
+ isReady(): boolean;
26
+ /** Clear the injected database (next access throws again). Mainly for tests. */
27
+ reset(): void;
28
+ }
29
+ interface DatabaseProviderOptions {
30
+ /** Error thrown when `db` is accessed before injection. Keep the product's
31
+ * existing wording so callers see a familiar message. */
32
+ notReadyMessage?: string;
33
+ }
34
+ /**
35
+ * Create a swappable database provider. `DB` is the injected instance's type
36
+ * (e.g. a drizzle `Database`); the proxy is typed as `DB` so callers keep full
37
+ * typing and their existing query syntax.
38
+ */
39
+ declare function createDatabaseProvider<DB extends object>(options?: DatabaseProviderOptions): DatabaseProvider<DB>;
40
+
41
+ export { type DatabaseProvider, type DatabaseProviderOptions, createDatabaseProvider };
@@ -0,0 +1,31 @@
1
+ // src/store/index.ts
2
+ function createDatabaseProvider(options = {}) {
3
+ const message = options.notReadyMessage ?? "Database not initialized \u2014 call setDatabase() first.";
4
+ let current = null;
5
+ const db = new Proxy({}, {
6
+ get(_target, prop) {
7
+ if (!current) throw new Error(message);
8
+ const value = current[prop];
9
+ return typeof value === "function" ? value.bind(current) : value;
10
+ },
11
+ has(_target, prop) {
12
+ return current !== null && prop in current;
13
+ }
14
+ });
15
+ return {
16
+ db,
17
+ setDatabase(database) {
18
+ current = database;
19
+ },
20
+ isReady() {
21
+ return current !== null;
22
+ },
23
+ reset() {
24
+ current = null;
25
+ }
26
+ };
27
+ }
28
+ export {
29
+ createDatabaseProvider
30
+ };
31
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/store/index.ts"],"sourcesContent":["/**\n * Swappable database provider — the seam that decouples the agent's persistence\n * from any one driver.\n *\n * The agent core (and the app's server modules) import a single `db` and use it\n * directly. That `db` is a lazy proxy: it forwards to whatever database instance\n * the runtime injects via {@link DatabaseProvider.setDatabase}. So the SAME core\n * runs on:\n * - Cloudflare D1 (`setDatabase(drizzle(d1, schema))`) — prod\n * - SQLite / miniflare (`setDatabase(drizzle(betterSqlite, schema))`) — eval / the portable inner shell\n * - libsql / Turso, Postgres (`setDatabase(drizzle(client, schema))`) — a future hosted DB\n *\n * Adding a new database is one adapter (a drizzle instance over a new driver) +\n * a `setDatabase` call. None of the modules importing `db` change. Substrate-\n * free and driver-agnostic: this module knows nothing about D1, drizzle, or any\n * schema — it only forwards property access to the injected instance.\n */\n\nexport interface DatabaseProvider<DB> {\n /** The injected database, as a lazy proxy. Throws (with `notReadyMessage`)\n * on any access before {@link setDatabase} is called. */\n readonly db: DB\n /** Inject the active database instance (any driver's client). */\n setDatabase(database: DB): void\n /** True once a database has been injected. */\n isReady(): boolean\n /** Clear the injected database (next access throws again). Mainly for tests. */\n reset(): void\n}\n\nexport interface DatabaseProviderOptions {\n /** Error thrown when `db` is accessed before injection. Keep the product's\n * existing wording so callers see a familiar message. */\n notReadyMessage?: string\n}\n\n/**\n * Create a swappable database provider. `DB` is the injected instance's type\n * (e.g. a drizzle `Database`); the proxy is typed as `DB` so callers keep full\n * typing and their existing query syntax.\n */\nexport function createDatabaseProvider<DB extends object>(\n options: DatabaseProviderOptions = {},\n): DatabaseProvider<DB> {\n const message = options.notReadyMessage ?? 'Database not initialized — call setDatabase() first.'\n let current: DB | null = null\n\n const db = new Proxy({} as DB, {\n get(_target, prop) {\n if (!current) throw new Error(message)\n const value = (current as Record<string | symbol, unknown>)[prop]\n // Bind methods to the real instance so `this` resolves correctly through\n // the proxy (works for drizzle's query builders and class-based stores).\n return typeof value === 'function' ? (value as (...args: unknown[]) => unknown).bind(current) : value\n },\n has(_target, prop) {\n return current !== null && prop in (current as object)\n },\n })\n\n return {\n db,\n setDatabase(database: DB) {\n current = database\n },\n isReady() {\n return current !== null\n },\n reset() {\n current = null\n },\n }\n}\n"],"mappings":";AAyCO,SAAS,uBACd,UAAmC,CAAC,GACd;AACtB,QAAM,UAAU,QAAQ,mBAAmB;AAC3C,MAAI,UAAqB;AAEzB,QAAM,KAAK,IAAI,MAAM,CAAC,GAAS;AAAA,IAC7B,IAAI,SAAS,MAAM;AACjB,UAAI,CAAC,QAAS,OAAM,IAAI,MAAM,OAAO;AACrC,YAAM,QAAS,QAA6C,IAAI;AAGhE,aAAO,OAAO,UAAU,aAAc,MAA0C,KAAK,OAAO,IAAI;AAAA,IAClG;AAAA,IACA,IAAI,SAAS,MAAM;AACjB,aAAO,YAAY,QAAQ,QAAS;AAAA,IACtC;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,YAAY,UAAc;AACxB,gBAAU;AAAA,IACZ;AAAA,IACA,UAAU;AACR,aAAO,YAAY;AAAA,IACrB;AAAA,IACA,QAAQ;AACN,gBAAU;AAAA,IACZ;AAAA,EACF;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-app",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "packageManager": "pnpm@10.33.4",
5
5
  "description": "Application-shell framework for Tangle agent products: a bounded tool loop, the structured agent→app tool side channel, integration-hub client, per-workspace billing, and crypto — composed over the Tangle agent substrate through typed seams.",
6
6
  "keywords": [
@@ -115,6 +115,11 @@
115
115
  "types": "./dist/redact/index.d.ts",
116
116
  "import": "./dist/redact/index.js",
117
117
  "default": "./dist/redact/index.js"
118
+ },
119
+ "./store": {
120
+ "types": "./dist/store/index.d.ts",
121
+ "import": "./dist/store/index.js",
122
+ "default": "./dist/store/index.js"
118
123
  }
119
124
  },
120
125
  "scripts": {