@skein-js/runtime 0.3.0 → 0.4.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
@@ -20,8 +20,8 @@ import { createExpressServer } from "@skein-js/express";
20
20
 
21
21
  const runtime = await buildRuntime({
22
22
  configPath: "/abs/path/to/langgraph.json",
23
- store: "postgres", // "memory" | "postgres" (postgres reads DATABASE_URL)
24
- queue: "redis", // "memory" | "redis" (redis reads REDIS_URL)
23
+ store: "postgres", // "memory" | "postgres" (postgres reads POSTGRES_URI)
24
+ queue: "redis", // "memory" | "redis" (redis reads REDIS_URI)
25
25
  });
26
26
 
27
27
  const server = await createExpressServer({ deps: runtime.deps, cors: runtime.cors });
@@ -33,13 +33,13 @@ await runtime.dispose();
33
33
  `store` and `queue` are **required** (no defaults — the CLI supplies its own flag defaults). The
34
34
  driver branches:
35
35
 
36
- - **`store: "postgres"`** connects `PostgresSkeinStore` (from `DATABASE_URL`), runs its migrations,
36
+ - **`store: "postgres"`** connects `PostgresSkeinStore` (from `POSTGRES_URI`), runs its migrations,
37
37
  and uses `PostgresSaver` as the LangGraph checkpointer.
38
- - **`queue: "redis"`** uses the BullMQ run queue + Redis Streams/pub-sub event bus (from `REDIS_URL`).
38
+ - **`queue: "redis"`** uses the BullMQ run queue + Redis Streams/pub-sub event bus (from `REDIS_URI`).
39
39
  - **`store: "memory"` + `queue: "memory"`** delegates to [`@skein-js/express`](../server-express)'s
40
40
  reloadable in-memory runtime, so `skein dev`'s hot-reload and cross-restart state persistence work.
41
41
 
42
- A missing `DATABASE_URL` / `REDIS_URL` throws `RuntimeConfigError`; if assembly fails part-way, any
42
+ A missing `POSTGRES_URI` / `REDIS_URI` throws `RuntimeConfigError`; if assembly fails part-way, any
43
43
  resources already created are disposed before rethrowing, so a failed build leaks nothing.
44
44
 
45
45
  Graph hot-reload (`reloadGraphs()`) works in every mode; `snapshotState`/`hydrateState` are present
package/dist/index.d.ts CHANGED
@@ -13,9 +13,9 @@ interface BuildRuntimeOptions {
13
13
  configPath: string;
14
14
  /** TS-capable importer (e.g. the CLI's vite loader). Omitted for plain JS/Node resolution. */
15
15
  importModule?: ModuleImporter;
16
- /** `"memory"` (default dev) or `"postgres"` (reads `DATABASE_URL`). */
16
+ /** `"memory"` (default dev) or `"postgres"` (reads `POSTGRES_URI`). */
17
17
  store: StoreDriver;
18
- /** `"memory"` (default dev) or `"redis"` (reads `REDIS_URL`). */
18
+ /** `"memory"` (default dev) or `"redis"` (reads `REDIS_URI`). */
19
19
  queue: QueueDriver;
20
20
  }
21
21
  interface SkeinRuntime {
package/dist/index.js CHANGED
@@ -165,9 +165,10 @@ async function buildRuntime(options) {
165
165
  await Promise.allSettled(disposers.map((dispose) => dispose()));
166
166
  };
167
167
  try {
168
+ const storeTtl = resolveStoreTtl(first.config.store?.ttl);
168
169
  const { skeinStore, checkpointer } = await (async () => {
169
170
  if (store === "postgres") {
170
- const databaseUrl = requireEnv("DATABASE_URL", "postgres");
171
+ const databaseUrl = requireEnv("POSTGRES_URI", "postgres");
171
172
  const index = await resolveStoreIndex(first.config.store?.index, {
172
173
  configDir: first.configDir,
173
174
  importModule
@@ -175,6 +176,7 @@ async function buildRuntime(options) {
175
176
  const connectionOptions = postgresConnectionOptions();
176
177
  const pgStore = await PostgresSkeinStore.connect(databaseUrl, {
177
178
  ...index ? { index } : {},
179
+ ...storeTtl ? { ttl: storeTtl } : {},
178
180
  ...connectionOptions
179
181
  });
180
182
  disposers.push(() => pgStore.close());
@@ -184,11 +186,24 @@ async function buildRuntime(options) {
184
186
  await saver.setup();
185
187
  return { skeinStore: pgStore, checkpointer: saver };
186
188
  }
187
- return { skeinStore: new MemorySkeinStore(), checkpointer: new MemorySaver() };
189
+ return {
190
+ skeinStore: new MemorySkeinStore(storeTtl ? { ttl: storeTtl } : void 0),
191
+ checkpointer: new MemorySaver()
192
+ };
188
193
  })();
194
+ if (storeTtl) {
195
+ const everyMs = (storeTtl.sweepIntervalMinutes ?? 60) * 6e4;
196
+ const sweeper = setInterval(() => {
197
+ skeinStore.store.sweepExpired().catch((error) => {
198
+ console.error("skein: store TTL sweep failed", error);
199
+ });
200
+ }, everyMs);
201
+ sweeper.unref();
202
+ disposers.push(async () => clearInterval(sweeper));
203
+ }
189
204
  const { runQueue, bus } = (() => {
190
205
  if (queue === "redis") {
191
- const redisUrl = requireEnv("REDIS_URL", "redis");
206
+ const redisUrl = requireEnv("REDIS_URI", "redis");
192
207
  const redisQueue = new RedisRunQueue(redisUrl);
193
208
  disposers.push(() => redisQueue.dispose());
194
209
  const redisBus = new RedisRunEventBus(redisUrl);
@@ -221,6 +236,16 @@ async function buildRuntime(options) {
221
236
  throw error;
222
237
  }
223
238
  }
239
+ function resolveStoreTtl(raw) {
240
+ if (!raw) return void 0;
241
+ const ttl = {};
242
+ if (typeof raw.default_ttl === "number") ttl.defaultTtl = raw.default_ttl;
243
+ if (typeof raw.refresh_on_read === "boolean") ttl.refreshOnRead = raw.refresh_on_read;
244
+ if (typeof raw.sweep_interval_minutes === "number") {
245
+ ttl.sweepIntervalMinutes = raw.sweep_interval_minutes;
246
+ }
247
+ return Object.keys(ttl).length > 0 ? ttl : void 0;
248
+ }
224
249
  export {
225
250
  RuntimeConfigError,
226
251
  buildRuntime,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skein-js/runtime",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Assembles skein-js ProtocolDeps from langgraph.json + selected drivers (memory/Postgres/Redis).",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Maina Wycliffe <wmmaina7@gmail.com>",
@@ -42,12 +42,12 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "cors": "^2.8.5",
45
- "@skein-js/agent-protocol": "0.3.0",
46
- "@skein-js/express": "0.3.0",
47
- "@skein-js/config": "0.3.0",
48
- "@skein-js/storage-memory": "0.3.0",
49
- "@skein-js/storage-postgres": "0.3.0",
50
- "@skein-js/redis": "0.3.0"
45
+ "@skein-js/agent-protocol": "0.4.0",
46
+ "@skein-js/config": "0.4.0",
47
+ "@skein-js/express": "0.4.0",
48
+ "@skein-js/storage-memory": "0.4.0",
49
+ "@skein-js/storage-postgres": "0.4.0",
50
+ "@skein-js/redis": "0.4.0"
51
51
  },
52
52
  "peerDependencies": {
53
53
  "@langchain/langgraph": "^1.4.0",
@@ -58,7 +58,7 @@
58
58
  "@langchain/langgraph": "^1.4.0",
59
59
  "@langchain/langgraph-checkpoint-postgres": "^1.0.4",
60
60
  "@types/cors": "^2.8.17",
61
- "@skein-js/test-support": "0.3.0"
61
+ "@skein-js/test-support": "0.4.0"
62
62
  },
63
63
  "publishConfig": {
64
64
  "access": "public"