tila-sdk 0.1.0 → 0.2.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 +127 -0
- package/dist/index.cjs +2028 -750
- package/dist/index.d.cts +941 -249
- package/dist/index.d.ts +941 -249
- package/dist/index.js +2021 -750
- package/dist/local.cjs +11506 -0
- package/dist/local.d.cts +9048 -0
- package/dist/local.d.ts +9048 -0
- package/dist/local.js +9553 -0
- package/package.json +29 -4
package/README.md
CHANGED
|
@@ -49,6 +49,133 @@ const updated = await entities.update("task-1", {
|
|
|
49
49
|
await entities.archive("task-1");
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
### `createTila` — one facade, local or remote
|
|
53
|
+
|
|
54
|
+
`createTila(config, token?)` returns a uniform facade exposing the same resource
|
|
55
|
+
methods (`tasks`, `records`, `claims`, `artifacts`, `gates`, `signals`,
|
|
56
|
+
`journal`, `presence`, `schema`, `summary`, `search`, `templates`, `tokens`)
|
|
57
|
+
regardless of backend. Swap `config.backend` without changing any call site.
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { createTila } from "tila-sdk";
|
|
61
|
+
|
|
62
|
+
// Cloudflare (HTTP) — token required
|
|
63
|
+
const tila = await createTila(
|
|
64
|
+
{ project_id: "my-project", backend: "cloudflare", worker_url: process.env.TILA_URL!, schema_version: 1, tila_version: "0", created_at: "" },
|
|
65
|
+
process.env.TILA_TOKEN!,
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
// Local (in-process SQLite) — no token; requires the optional `better-sqlite3` peer dep
|
|
69
|
+
const local = await createTila({
|
|
70
|
+
project_id: "my-project",
|
|
71
|
+
backend: "local",
|
|
72
|
+
local: { db_path: ".tila/project.db", artifacts_path: ".tila/artifacts" },
|
|
73
|
+
schema_version: 1,
|
|
74
|
+
tila_version: "0",
|
|
75
|
+
created_at: "",
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
await tila.tasks.create("task-1", "task", { title: "uniform call site" });
|
|
79
|
+
await local.tasks.create("task-1", "task", { title: "uniform call site" });
|
|
80
|
+
local.close(); // closes the SQLite connection (no-op for cloudflare)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
> **`better-sqlite3` peer dep:** the local backend lazily loads `better-sqlite3`
|
|
84
|
+
> (an optional peer dependency). Install it for local mode; cloudflare mode never
|
|
85
|
+
> touches it. Token issuance (`tila.tokens.*`) is HTTP-only and throws in local.
|
|
86
|
+
|
|
87
|
+
The `close()` method is the canonical lifecycle handle for both backends: it is a
|
|
88
|
+
no-op for cloudflare and closes the SQLite connection for local. It is safe to call
|
|
89
|
+
more than once (double-close safe).
|
|
90
|
+
|
|
91
|
+
In local mode, a few facade methods have no in-process equivalent and throw
|
|
92
|
+
`LocalUnsupportedError` instead of silently no-op'ing:
|
|
93
|
+
|
|
94
|
+
- `tokens.issue` / `tokens.revoke` / `tokens.list` (the D1 global token store is a
|
|
95
|
+
Worker/Cloudflare concern).
|
|
96
|
+
- `artifacts.upload` and `artifacts.download` (binary R2 multipart upload/download —
|
|
97
|
+
local consumers use the content-addressed text primitives `artifacts.writeText` /
|
|
98
|
+
`artifacts.readText` instead).
|
|
99
|
+
|
|
100
|
+
### `tila-sdk/local` — direct local backend
|
|
101
|
+
|
|
102
|
+
For full control over the local stack (without the `createTila` facade), import the
|
|
103
|
+
heavy entry directly. It is a separate package export so the SQLite/`node:fs` stack
|
|
104
|
+
never loads from the main (zod-only) entry:
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { createTilaLocal } from "tila-sdk/local";
|
|
108
|
+
|
|
109
|
+
const { project, artifacts, close } = await createTilaLocal({
|
|
110
|
+
dbPath: ".tila/project.db", // SQLite file (created if absent)
|
|
111
|
+
artifactsPath: ".tila/artifacts", // blob root directory
|
|
112
|
+
project: "my-project", // required — scopes artifact keys
|
|
113
|
+
org: "my-org", // optional, defaults to "local"
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// `project` is the full @tila/core backend surface (Entity/Coordination/Journal/
|
|
117
|
+
// Gate/Signal/Schema/Summary/Record); `artifacts` is the ArtifactBackend.
|
|
118
|
+
close(); // closes the underlying better-sqlite3 connection
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
> Note: the `createTilaLocal` option keys are camelCase — `dbPath`, `artifactsPath`,
|
|
122
|
+
> `org`, `project`. (The `createTila` facade's `config.local` section uses snake_case
|
|
123
|
+
> `db_path` / `artifacts_path` to mirror the `[local]` config file; the direct
|
|
124
|
+
> `createTilaLocal` options object is camelCase.)
|
|
125
|
+
|
|
126
|
+
### `better-sqlite3` — optional peer dependency
|
|
127
|
+
|
|
128
|
+
`better-sqlite3` is an **optional peer dependency** with range **`>=11 <13`**. The
|
|
129
|
+
**tested / CI-exercised** version is **12.x (currently `12.10.0`)**; 11.x is declared
|
|
130
|
+
supported but is *not* exercised in CI. Install it only when you use the local
|
|
131
|
+
backend:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
npm i better-sqlite3
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
If it (or its drizzle adapter) is missing, calling into the local backend throws
|
|
138
|
+
`MissingNativeDriverError` with the exact message:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
tila-sdk/local requires the optional peer dependency 'better-sqlite3'. Run: npm i better-sqlite3
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Importing `tila-sdk/local` never loads the native binary — only *calling*
|
|
145
|
+
`createTilaLocal` (or `createTila({ backend: "local" })`) does.
|
|
146
|
+
|
|
147
|
+
> **No prebuilt binaries for musl/Alpine or Windows-arm64.** `better-sqlite3` ships
|
|
148
|
+
> prebuilt binaries for common platforms but **not** musl-libc (Alpine) or
|
|
149
|
+
> Windows-arm64. On those, the consumer needs a build toolchain (Python + make + a C
|
|
150
|
+
> compiler) so `better-sqlite3` can compile from source on install.
|
|
151
|
+
|
|
152
|
+
> **`skipLibCheck: true` required** in your `tsconfig.json` when consuming
|
|
153
|
+
> `tila-sdk/local` types. The bundled `better-sqlite3` / `drizzle-orm` declarations
|
|
154
|
+
> do not fully round-trip through the dts rollup (a known rollup-dts limitation). This
|
|
155
|
+
> does **not** affect type-checking of *your own* code — `skipLibCheck` only skips
|
|
156
|
+
> re-checking library `.d.ts` internals (the ecosystem default, also used in this
|
|
157
|
+
> monorepo).
|
|
158
|
+
|
|
159
|
+
### Browser / HTTP-only consumers
|
|
160
|
+
|
|
161
|
+
The main `tila-sdk` entry stays zod-only — no native stack is statically reachable
|
|
162
|
+
from it (enforced by a bundle-hygiene test). Browsers and any HTTP-only environment
|
|
163
|
+
use the cloudflare backend; they never touch `better-sqlite3` or `node:fs`.
|
|
164
|
+
|
|
165
|
+
### Local-mode behavior divergences vs remote
|
|
166
|
+
|
|
167
|
+
Local mode presents the same facade shape, but a handful of methods diverge from the
|
|
168
|
+
HTTP backend. These are intentional and called out so consumers are not surprised:
|
|
169
|
+
|
|
170
|
+
| Method | Local behavior | Why |
|
|
171
|
+
|--------|----------------|-----|
|
|
172
|
+
| `schema.history` | Returns `[]` | Dead on **both** sides — the Worker exposes no schema-history route either, so the cloudflare branch would 404. (The data exists in `_schema_history`; it is simply not surfaced.) |
|
|
173
|
+
| `presence.listAll` | Returns only **active** machines (every row `active: true`) | The embedded backend's `listPresence()` already filters to active machines by TTL; remote additionally includes stale machines as `active: false`. |
|
|
174
|
+
| `artifacts.writeText` | Returns `deduplicated: false` and drops `tags` | The embedded artifacts table has no `tags` column, and the local write path does not report dedup. |
|
|
175
|
+
| `tasks.list` | Ignores `compact`, emits no pagination cursor | `compact` is an HTTP-only projection; the local list is non-paginated (no `next_cursor`/`total`). |
|
|
176
|
+
| `templates.list` | `variables` derived from `{{placeholders}}` | Local derives variables by scanning each template's entity data for `{{name}}` placeholders (`/\{\{(\w+)\}\}/`). |
|
|
177
|
+
| `idempotency_key` (e.g. on `claims.acquire`) | Accepted but **not honored** | Remote dedups retries via D1; local relies on primary-key-level dedup instead — a retried create of an existing id fails rather than duplicating. Full idempotency is single-machine-low-risk and remote-only. (The embedded `_idempotency` table + `check/storeIdempotency` exist but are intentionally unwired.) |
|
|
178
|
+
|
|
52
179
|
### Constructor Options
|
|
53
180
|
|
|
54
181
|
| Option | Type | Default | Description |
|