@skein-js/server-kit 0.13.0 → 0.13.1

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,7 @@
1
1
  # @skein-js/server-kit
2
2
 
3
+ [![npm](https://img.shields.io/npm/v/%40skein-js%2Fserver-kit?logo=npm&color=cb3837)](https://www.npmjs.com/package/@skein-js/server-kit) [![downloads](https://img.shields.io/npm/dm/%40skein-js%2Fserver-kit?color=blue)](https://www.npmjs.com/package/@skein-js/server-kit) [![license](https://img.shields.io/npm/l/%40skein-js%2Fserver-kit?color=green)](../../LICENSE)
4
+
3
5
  > Shared, framework-agnostic building blocks for skein-js HTTP adapters.
4
6
 
5
7
  Part of **[skein-js](../../README.md)** — the open-source alternative to LangGraph Platform for TypeScript: a self-hosted [Agent Protocol](https://github.com/langchain-ai/agent-protocol) server for [LangGraph.js](https://github.com/langchain-ai/langgraphjs), and a drop-in replacement for the LangGraph CLI.
@@ -107,9 +109,16 @@ Pass `overrides` to swap in production drivers or an auth engine while keeping t
107
109
  - **`resolveMaxPageSize(explicit?, env?): number`** — the same chain for the store page bound:
108
110
  explicit `maxPageSize` → `SKEIN_MAX_PAGE_SIZE` → `DEFAULT_MAX_PAGE_SIZE` (1000). Every driver applies
109
111
  it to list/search, including when the caller asks for no limit.
112
+ - **`resolveStoreTtl(raw?)` / `resolveThreadTtl(raw?)`** — map the `langgraph.json` `store.ttl` and
113
+ `checkpointer.ttl` blocks (snake_case, minutes) onto the drivers' camelCase `StoreTtlConfig` /
114
+ `ThreadTtlConfig`; `undefined` when unset, so nothing expires unless asked. Plus the raw input types
115
+ `RawStoreTtl` / `RawThreadTtl`. They live here rather than in `@skein-js/runtime` because **both**
116
+ assembly paths need them and neither owns the other — resolving a block in only one is how a TTL
117
+ came to work under `skein start` and silently do nothing under `skein dev`.
110
118
  - **`loadInMemoryRuntime` / `loadReloadableInMemoryRuntime`** — assemble a `ProtocolDeps` from a
111
- `langgraph.json` using in-process drivers. The reloadable variant adds `reloadGraphs` /
112
- `snapshotState` / `hydrateState` (what powers `skein dev`'s hot reload + cross-restart persistence).
119
+ `langgraph.json` using in-process drivers, reading both TTL blocks itself. The reloadable variant
120
+ adds `reloadGraphs` / `snapshotState` / `hydrateState` (what powers `skein dev`'s hot reload +
121
+ cross-restart persistence).
113
122
  - **`readLanggraphDevState` / `loadSnapshotIntoStore` / `describeSnapshot`** — read an existing
114
123
  `.langgraph_api/` directory and reconstruct a `DevStateSnapshot`, so adopting skein carries local
115
124
  state over losslessly.
@@ -155,6 +155,27 @@ function embedInMemoryGraphs(graphs, overrides = {}) {
155
155
  }
156
156
  var createInMemoryDeps = embedInMemoryGraphs;
157
157
 
158
+ // src/ttl-config.ts
159
+ function resolveThreadTtl(raw) {
160
+ if (!raw) return void 0;
161
+ const ttl = {};
162
+ if (typeof raw.default_ttl === "number") ttl.defaultTtl = raw.default_ttl;
163
+ if (typeof raw.sweep_interval_minutes === "number") {
164
+ ttl.sweepIntervalMinutes = raw.sweep_interval_minutes;
165
+ }
166
+ return Object.keys(ttl).length > 0 ? ttl : void 0;
167
+ }
168
+ function resolveStoreTtl(raw) {
169
+ if (!raw) return void 0;
170
+ const ttl = {};
171
+ if (typeof raw.default_ttl === "number") ttl.defaultTtl = raw.default_ttl;
172
+ if (typeof raw.refresh_on_read === "boolean") ttl.refreshOnRead = raw.refresh_on_read;
173
+ if (typeof raw.sweep_interval_minutes === "number") {
174
+ ttl.sweepIntervalMinutes = raw.sweep_interval_minutes;
175
+ }
176
+ return Object.keys(ttl).length > 0 ? ttl : void 0;
177
+ }
178
+
158
179
  // src/in-memory-runtime.ts
159
180
  function toGraphResolver(graphs) {
160
181
  return {
@@ -185,7 +206,13 @@ async function loadReloadableInMemoryRuntime(configPath, importModule, staticSch
185
206
  load: (graphId) => current.load(graphId),
186
207
  schemas: async (graphId) => await current.schemas(graphId)
187
208
  };
188
- const store = new MemorySkeinStore2({ maxPageSize: resolveMaxPageSize() });
209
+ const threadTtl = resolveThreadTtl(first.config.checkpointer?.ttl);
210
+ const storeTtl = resolveStoreTtl(first.config.store?.ttl);
211
+ const store = new MemorySkeinStore2({
212
+ maxPageSize: resolveMaxPageSize(),
213
+ ...threadTtl ? { threadTtl } : {},
214
+ ...storeTtl ? { ttl: storeTtl } : {}
215
+ });
189
216
  const checkpointer = new MemorySaver2();
190
217
  const deps = {
191
218
  store,
@@ -196,6 +223,8 @@ async function loadReloadableInMemoryRuntime(configPath, importModule, staticSch
196
223
  bus: new MemoryRunEventBus2(resolveMemoryBusLimits()),
197
224
  checkpointer,
198
225
  auth: await loadAuthEngine(first.config.auth, { configDir: first.configDir, importModule }),
226
+ // Present only when configured — its presence is what starts the thread TTL sweeper.
227
+ ...threadTtl ? { threadTtl } : {},
199
228
  ...extraDeps
200
229
  };
201
230
  return {
@@ -232,6 +261,8 @@ export {
232
261
  graphMapToResolver,
233
262
  embedInMemoryGraphs,
234
263
  createInMemoryDeps,
264
+ resolveThreadTtl,
265
+ resolveStoreTtl,
235
266
  loadInMemoryRuntime,
236
267
  loadReloadableInMemoryRuntime
237
268
  };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  loadInMemoryRuntime,
3
3
  loadReloadableInMemoryRuntime
4
- } from "./chunk-QOHYARHD.js";
4
+ } from "./chunk-LJGZJ5L7.js";
5
5
  import "./chunk-JUBBCC7R.js";
6
6
  export {
7
7
  loadInMemoryRuntime,
package/dist/index.d.ts CHANGED
@@ -6,9 +6,9 @@ export { CorsOptions } from 'cors';
6
6
  import { MemoryRunEventBusOptions } from '@skein-js/storage-memory';
7
7
  import { D as DevStateSnapshot } from './dev-BfYYRfEB.js';
8
8
  export { a as DevStateCounts } from './dev-BfYYRfEB.js';
9
+ import { StoreTtlConfig, ThreadTtlConfig } from '@skein-js/core';
9
10
  import { CompiledGraph } from '@langchain/langgraph';
10
11
  import { ServerResponse } from 'node:http';
11
- import '@skein-js/core';
12
12
 
13
13
  interface SkeinRuntimeCommonOptions {
14
14
  /**
@@ -454,6 +454,32 @@ declare function loadReloadableInMemoryRuntime(configPath: string, importModule?
454
454
  */
455
455
  extraDeps?: Partial<Omit<ProtocolDeps, "graphs">>): Promise<ReloadableInMemoryRuntime>;
456
456
 
457
+ /** The raw `checkpointer.ttl` block as `langgraph.json` spells it. */
458
+ interface RawThreadTtl {
459
+ default_ttl?: number;
460
+ strategy?: "delete";
461
+ sweep_interval_minutes?: number;
462
+ }
463
+ /**
464
+ * Map the raw block to {@link ThreadTtlConfig}, or `undefined` when nothing is set — so threads never
465
+ * expire unless asked to, and no sweeper is started.
466
+ *
467
+ * `strategy` is read only to be validated by the config schema: `"delete"` is the only thing an
468
+ * expired thread can become, so there is nothing for the drivers to branch on.
469
+ */
470
+ declare function resolveThreadTtl(raw: RawThreadTtl | undefined): ThreadTtlConfig | undefined;
471
+ /** The raw `store.ttl` block as `langgraph.json` spells it. */
472
+ interface RawStoreTtl {
473
+ default_ttl?: number;
474
+ refresh_on_read?: boolean;
475
+ sweep_interval_minutes?: number;
476
+ }
477
+ /**
478
+ * Map the raw `store.ttl` block to {@link StoreTtlConfig}, or `undefined` when nothing is set — so
479
+ * store items never expire unless asked to.
480
+ */
481
+ declare function resolveStoreTtl(raw: RawStoreTtl | undefined): StoreTtlConfig | undefined;
482
+
457
483
  type AnyCompiledGraph = CompiledGraph<any>;
458
484
  /**
459
485
  * A graph you can embed in code: any compiled LangGraph.js graph, or a factory that builds one per run
@@ -649,4 +675,4 @@ type RuntimeGlobal = typeof globalThis & {
649
675
  /** Detect Node, Bun, or Deno without importing a runtime-specific module. */
650
676
  declare function detectRuntimeCapabilities(scope?: RuntimeGlobal): RuntimeCapabilities;
651
677
 
652
- export { type ConsoleLogLevel, type ConsoleLoggerOptions, type CorsSetting, DEFAULT_HEAP_SAMPLE_MS, DEFAULT_HEAP_WARN_PERCENT, DevStateSnapshot, type EmbeddableGraph, type FileReader, HEAP_REARM_MARGIN_PERCENT, HEAP_REARM_PERCENT, type HeapHeadroom, type HeapPressureContext, type HeapPressureMonitor, type HeapPressureMonitorOptions, type InMemoryRuntimeConfig, type IntervalHandle, type LanggraphCorsConfig, type ReloadableInMemoryRuntime, type ResolvedMemoryBusLimits, type ResolvedProtocolRuntime, type ResolvedRuntimeDeps, type RuntimeCapabilities, type RuntimeMemorySnapshot, type RuntimeSignalSubscription, type SkeinRuntimeCommonOptions, type SkeinRuntimeOptions, allowedOrigin, applyNodeCors, checkHeapHeadroom, corsFromHttpConfig, corsPreflightHeaders, corsResponseHeaders, createConsoleLogger, createInMemoryDeps, describeError, describeHeapHeadroom, describePoolPressure, detectRuntimeCapabilities, disabledRoutesFromHttpConfig, embedInMemoryGraphs, formatLogMeta, graphMapToResolver, joinList, loadInMemoryRuntime, loadReloadableInMemoryRuntime, normalizeEmbeddableGraphs, readContainerMemoryLimit, resolveCronTickMs, resolveHeapPressureOptions, resolveMaxPageSize, resolveMemoryBusLimits, resolveProtocolRuntime, resolveRunConcurrency, resolveRunTimeoutMs, resolveRuntimeDeps, resolveShutdownGraceMs, routeMatcherFor, routesFromHttpConfig, runFailureIdentity, sendNodeError, sendNodePreflight, sendNodeResponse, startHeapPressureMonitor, stripBasePath, toCorsOptions };
678
+ export { type ConsoleLogLevel, type ConsoleLoggerOptions, type CorsSetting, DEFAULT_HEAP_SAMPLE_MS, DEFAULT_HEAP_WARN_PERCENT, DevStateSnapshot, type EmbeddableGraph, type FileReader, HEAP_REARM_MARGIN_PERCENT, HEAP_REARM_PERCENT, type HeapHeadroom, type HeapPressureContext, type HeapPressureMonitor, type HeapPressureMonitorOptions, type InMemoryRuntimeConfig, type IntervalHandle, type LanggraphCorsConfig, type RawStoreTtl, type RawThreadTtl, type ReloadableInMemoryRuntime, type ResolvedMemoryBusLimits, type ResolvedProtocolRuntime, type ResolvedRuntimeDeps, type RuntimeCapabilities, type RuntimeMemorySnapshot, type RuntimeSignalSubscription, type SkeinRuntimeCommonOptions, type SkeinRuntimeOptions, allowedOrigin, applyNodeCors, checkHeapHeadroom, corsFromHttpConfig, corsPreflightHeaders, corsResponseHeaders, createConsoleLogger, createInMemoryDeps, describeError, describeHeapHeadroom, describePoolPressure, detectRuntimeCapabilities, disabledRoutesFromHttpConfig, embedInMemoryGraphs, formatLogMeta, graphMapToResolver, joinList, loadInMemoryRuntime, loadReloadableInMemoryRuntime, normalizeEmbeddableGraphs, readContainerMemoryLimit, resolveCronTickMs, resolveHeapPressureOptions, resolveMaxPageSize, resolveMemoryBusLimits, resolveProtocolRuntime, resolveRunConcurrency, resolveRunTimeoutMs, resolveRuntimeDeps, resolveShutdownGraceMs, resolveStoreTtl, resolveThreadTtl, routeMatcherFor, routesFromHttpConfig, runFailureIdentity, sendNodeError, sendNodePreflight, sendNodeResponse, startHeapPressureMonitor, stripBasePath, toCorsOptions };
package/dist/index.js CHANGED
@@ -11,9 +11,11 @@ import {
11
11
  requirePositiveInteger,
12
12
  resolveMaxPageSize,
13
13
  resolveMemoryBusLimits,
14
+ resolveStoreTtl,
15
+ resolveThreadTtl,
14
16
  routesFromHttpConfig,
15
17
  toCorsOptions
16
- } from "./chunk-QOHYARHD.js";
18
+ } from "./chunk-LJGZJ5L7.js";
17
19
  import "./chunk-JUBBCC7R.js";
18
20
 
19
21
  // src/resolve-runtime.ts
@@ -162,7 +164,7 @@ function resolveLogger(option, injected, frameworkLogger) {
162
164
  return option ?? frameworkLogger;
163
165
  }
164
166
  async function resolveRuntimeDeps(options, frameworkLogger) {
165
- const loaded = options.deps ? { deps: options.deps, cors: void 0, routes: skeinRoutes } : await (await import("./in-memory-runtime-32UYJRVJ.js")).loadInMemoryRuntime(options.config, options.importModule);
167
+ const loaded = options.deps ? { deps: options.deps, cors: void 0, routes: skeinRoutes } : await (await import("./in-memory-runtime-KII6KQ4U.js")).loadInMemoryRuntime(options.config, options.importModule);
166
168
  const logger = resolveLogger(options.logger, loaded.deps.logger, frameworkLogger);
167
169
  if (logger && !loaded.deps.logger) loaded.deps.logger = logger;
168
170
  return { deps: loaded.deps, cors: loaded.cors, routes: loaded.routes, logger };
@@ -680,6 +682,8 @@ export {
680
682
  resolveRunTimeoutMs,
681
683
  resolveRuntimeDeps,
682
684
  resolveShutdownGraceMs,
685
+ resolveStoreTtl,
686
+ resolveThreadTtl,
683
687
  routeMatcherFor,
684
688
  routesFromHttpConfig,
685
689
  runFailureIdentity,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skein-js/server-kit",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
4
4
  "description": "Shared, framework-agnostic building blocks for skein-js HTTP adapters — in-memory dev runtime, LangGraph dev-state import, and langgraph.json CORS mapping.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Maina Wycliffe <wmmaina7@gmail.com>",
@@ -49,10 +49,10 @@
49
49
  "cors": "^2.8.5",
50
50
  "superjson": "^2.2.6",
51
51
  "zod": "^3.25.76",
52
- "@skein-js/agent-protocol": "0.13.0",
53
- "@skein-js/config": "0.13.0",
54
- "@skein-js/core": "0.13.0",
55
- "@skein-js/storage-memory": "0.13.0"
52
+ "@skein-js/core": "0.13.1",
53
+ "@skein-js/storage-memory": "0.13.1",
54
+ "@skein-js/config": "0.13.1",
55
+ "@skein-js/agent-protocol": "0.13.1"
56
56
  },
57
57
  "peerDependencies": {
58
58
  "@langchain/langgraph": "^1.4.0"