@agentick/core 0.2.1 → 0.3.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.
Files changed (94) hide show
  1. package/README.md +210 -23
  2. package/dist/.tsbuildinfo.build +1 -1
  3. package/dist/agentick-instance.d.ts.map +1 -1
  4. package/dist/agentick-instance.js +125 -119
  5. package/dist/agentick-instance.js.map +1 -1
  6. package/dist/app/session-store.d.ts +1 -1
  7. package/dist/app/session-store.js +1 -1
  8. package/dist/app/session.d.ts +26 -17
  9. package/dist/app/session.d.ts.map +1 -1
  10. package/dist/app/session.js +220 -202
  11. package/dist/app/session.js.map +1 -1
  12. package/dist/app/types.d.ts +229 -148
  13. package/dist/app/types.d.ts.map +1 -1
  14. package/dist/com/object-model.d.ts +7 -4
  15. package/dist/com/object-model.d.ts.map +1 -1
  16. package/dist/com/object-model.js +13 -4
  17. package/dist/com/object-model.js.map +1 -1
  18. package/dist/compiler/fiber-compiler.d.ts +8 -16
  19. package/dist/compiler/fiber-compiler.d.ts.map +1 -1
  20. package/dist/compiler/fiber-compiler.js +10 -31
  21. package/dist/compiler/fiber-compiler.js.map +1 -1
  22. package/dist/component/component.d.ts +6 -6
  23. package/dist/component/component.d.ts.map +1 -1
  24. package/dist/hooks/com-state.d.ts +14 -1
  25. package/dist/hooks/com-state.d.ts.map +1 -1
  26. package/dist/hooks/com-state.js +28 -2
  27. package/dist/hooks/com-state.js.map +1 -1
  28. package/dist/hooks/context-info.d.ts +2 -35
  29. package/dist/hooks/context-info.d.ts.map +1 -1
  30. package/dist/hooks/context-info.js +8 -0
  31. package/dist/hooks/context-info.js.map +1 -1
  32. package/dist/hooks/context.d.ts +1 -2
  33. package/dist/hooks/context.d.ts.map +1 -1
  34. package/dist/hooks/context.js +1 -2
  35. package/dist/hooks/context.js.map +1 -1
  36. package/dist/hooks/data.d.ts +18 -1
  37. package/dist/hooks/data.d.ts.map +1 -1
  38. package/dist/hooks/data.js +13 -2
  39. package/dist/hooks/data.js.map +1 -1
  40. package/dist/hooks/index.d.ts +5 -3
  41. package/dist/hooks/index.d.ts.map +1 -1
  42. package/dist/hooks/index.js +5 -1
  43. package/dist/hooks/index.js.map +1 -1
  44. package/dist/hooks/resolved.d.ts +2 -0
  45. package/dist/hooks/resolved.d.ts.map +1 -0
  46. package/dist/hooks/resolved.js +6 -0
  47. package/dist/hooks/resolved.js.map +1 -0
  48. package/dist/hooks/runtime-context.d.ts +45 -0
  49. package/dist/hooks/runtime-context.d.ts.map +1 -1
  50. package/dist/hooks/runtime-context.js +35 -0
  51. package/dist/hooks/runtime-context.js.map +1 -1
  52. package/dist/hooks/timeline.d.ts +10 -0
  53. package/dist/hooks/timeline.d.ts.map +1 -0
  54. package/dist/hooks/timeline.js +13 -0
  55. package/dist/hooks/timeline.js.map +1 -0
  56. package/dist/index.d.ts +2 -1
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +8 -0
  59. package/dist/index.js.map +1 -1
  60. package/dist/jsx/components/timeline.d.ts.map +1 -1
  61. package/dist/jsx/components/timeline.js +11 -11
  62. package/dist/jsx/components/timeline.js.map +1 -1
  63. package/dist/local-transport.d.ts +31 -0
  64. package/dist/local-transport.d.ts.map +1 -0
  65. package/dist/local-transport.js +119 -0
  66. package/dist/local-transport.js.map +1 -0
  67. package/dist/model/model.d.ts +0 -2
  68. package/dist/model/model.d.ts.map +1 -1
  69. package/dist/model/model.js.map +1 -1
  70. package/dist/procedure/index.d.ts.map +1 -1
  71. package/dist/testing/index.d.ts +2 -0
  72. package/dist/testing/index.d.ts.map +1 -1
  73. package/dist/testing/index.js +2 -0
  74. package/dist/testing/index.js.map +1 -1
  75. package/dist/testing/mock-app.d.ts.map +1 -1
  76. package/dist/testing/mock-app.js +5 -15
  77. package/dist/testing/mock-app.js.map +1 -1
  78. package/dist/testing/mocks.d.ts +2 -3
  79. package/dist/testing/mocks.d.ts.map +1 -1
  80. package/dist/testing/mocks.js +2 -3
  81. package/dist/testing/mocks.js.map +1 -1
  82. package/dist/testing/render-agent.d.ts +1 -1
  83. package/dist/testing/render-agent.d.ts.map +1 -1
  84. package/dist/testing/render-agent.js +5 -5
  85. package/dist/testing/render-agent.js.map +1 -1
  86. package/dist/testing/test-environment.d.ts +122 -0
  87. package/dist/testing/test-environment.d.ts.map +1 -0
  88. package/dist/testing/test-environment.js +126 -0
  89. package/dist/testing/test-environment.js.map +1 -0
  90. package/package.json +2 -2
  91. package/dist/hibernation/index.d.ts +0 -126
  92. package/dist/hibernation/index.d.ts.map +0 -1
  93. package/dist/hibernation/index.js +0 -127
  94. package/dist/hibernation/index.js.map +0 -1
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Test Environment Factory
3
+ *
4
+ * Creates mock ExecutionEnvironment instances for testing.
5
+ * Tracks all lifecycle hook invocations for assertions.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const { environment, tracker } = createTestEnvironment({
10
+ * name: "test",
11
+ * interceptTools: { my_tool: "intercepted!" },
12
+ * });
13
+ *
14
+ * const app = createApp(Agent, { model, environment });
15
+ * // ... run agent ...
16
+ *
17
+ * expect(tracker.initCalls).toHaveLength(1);
18
+ * expect(tracker.prepareModelInputCalls).toHaveLength(1);
19
+ * expect(tracker.toolCalls).toHaveLength(1);
20
+ * ```
21
+ */
22
+ import type { ExecutionEnvironment } from "../app/types";
23
+ import type { COMInput } from "../com/types";
24
+ import type { ExecutableTool } from "../tool/tool";
25
+ import type { ToolCall, ToolResult } from "@agentick/shared";
26
+ export interface TestEnvironmentOptions {
27
+ /**
28
+ * Environment name.
29
+ * @default "test"
30
+ */
31
+ name?: string;
32
+ /**
33
+ * Tool names to intercept. Values are either a string (becomes the result text)
34
+ * or a function that receives the ToolCall and returns a ToolResult.
35
+ * Non-intercepted tools pass through to normal execution.
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * // Static string result
40
+ * interceptTools: { execute: "sandbox result" }
41
+ *
42
+ * // Dynamic function result
43
+ * interceptTools: {
44
+ * execute: (call) => ({
45
+ * id: call.id, toolUseId: call.id, name: call.name,
46
+ * success: true, content: [{ type: "text", text: `ran: ${call.input.code}` }],
47
+ * }),
48
+ * }
49
+ * ```
50
+ */
51
+ interceptTools?: Record<string, string | ((call: ToolCall) => ToolResult | Promise<ToolResult>)>;
52
+ /**
53
+ * Transform function for prepareModelInput.
54
+ * If not provided, input passes through unchanged.
55
+ */
56
+ transformInput?: (compiled: COMInput, tools: ExecutableTool[]) => COMInput | Promise<COMInput>;
57
+ /**
58
+ * Data to add to snapshot during onPersist.
59
+ */
60
+ persistData?: Record<string, unknown>;
61
+ }
62
+ export interface EnvironmentTracker {
63
+ /** All onSessionInit calls (session IDs) */
64
+ initCalls: string[];
65
+ /** All prepareModelInput calls */
66
+ prepareModelInputCalls: Array<{
67
+ tools: string[];
68
+ }>;
69
+ /** All executeToolCall calls */
70
+ toolCalls: Array<{
71
+ name: string;
72
+ intercepted: boolean;
73
+ }>;
74
+ /** All onPersist calls (session IDs) */
75
+ persistCalls: string[];
76
+ /** All onRestore calls (session IDs) */
77
+ restoreCalls: string[];
78
+ /** All onDestroy calls (session IDs) */
79
+ destroyCalls: string[];
80
+ /** Reset all tracked calls */
81
+ reset(): void;
82
+ }
83
+ export interface TestEnvironmentResult {
84
+ /** The environment instance to pass to AppOptions */
85
+ environment: ExecutionEnvironment;
86
+ /** Tracker for asserting lifecycle calls */
87
+ tracker: EnvironmentTracker;
88
+ }
89
+ /**
90
+ * Create a test execution environment with call tracking.
91
+ *
92
+ * @example Basic usage
93
+ * ```typescript
94
+ * const { environment, tracker } = createTestEnvironment();
95
+ * const app = createApp(Agent, { model, environment });
96
+ * const session = await app.session();
97
+ * await session.send({ messages: [...] }).result;
98
+ *
99
+ * expect(tracker.initCalls).toHaveLength(1);
100
+ * expect(tracker.prepareModelInputCalls).toHaveLength(1);
101
+ * ```
102
+ *
103
+ * @example Intercepting tools
104
+ * ```typescript
105
+ * const { environment, tracker } = createTestEnvironment({
106
+ * interceptTools: { execute: "sandboxed!" },
107
+ * });
108
+ * // When model calls "execute" tool, it gets "sandboxed!" instead of real execution
109
+ * ```
110
+ *
111
+ * @example Transforming model input
112
+ * ```typescript
113
+ * const { environment } = createTestEnvironment({
114
+ * transformInput: (compiled, tools) => ({
115
+ * ...compiled,
116
+ * tools: [], // Remove all tools from model input
117
+ * }),
118
+ * });
119
+ * ```
120
+ */
121
+ export declare function createTestEnvironment(options?: TestEnvironmentOptions): TestEnvironmentResult;
122
+ //# sourceMappingURL=test-environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-environment.d.ts","sourceRoot":"","sources":["../../src/testing/test-environment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAA+B,MAAM,cAAc,CAAC;AACtF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAM7D,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;;;;;;;;;;;;;;;;OAkBG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,QAAQ,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAEjG;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE/F;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,kCAAkC;IAClC,sBAAsB,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACnD,gCAAgC;IAChC,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACzD,wCAAwC;IACxC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,wCAAwC;IACxC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,wCAAwC;IACxC,YAAY,EAAE,MAAM,EAAE,CAAC;IAEvB,8BAA8B;IAC9B,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,qDAAqD;IACrD,WAAW,EAAE,oBAAoB,CAAC;IAClC,4CAA4C;IAC5C,OAAO,EAAE,kBAAkB,CAAC;CAC7B;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,GAAG,qBAAqB,CAiFjG"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Test Environment Factory
3
+ *
4
+ * Creates mock ExecutionEnvironment instances for testing.
5
+ * Tracks all lifecycle hook invocations for assertions.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const { environment, tracker } = createTestEnvironment({
10
+ * name: "test",
11
+ * interceptTools: { my_tool: "intercepted!" },
12
+ * });
13
+ *
14
+ * const app = createApp(Agent, { model, environment });
15
+ * // ... run agent ...
16
+ *
17
+ * expect(tracker.initCalls).toHaveLength(1);
18
+ * expect(tracker.prepareModelInputCalls).toHaveLength(1);
19
+ * expect(tracker.toolCalls).toHaveLength(1);
20
+ * ```
21
+ */
22
+ // ============================================================================
23
+ // Factory
24
+ // ============================================================================
25
+ /**
26
+ * Create a test execution environment with call tracking.
27
+ *
28
+ * @example Basic usage
29
+ * ```typescript
30
+ * const { environment, tracker } = createTestEnvironment();
31
+ * const app = createApp(Agent, { model, environment });
32
+ * const session = await app.session();
33
+ * await session.send({ messages: [...] }).result;
34
+ *
35
+ * expect(tracker.initCalls).toHaveLength(1);
36
+ * expect(tracker.prepareModelInputCalls).toHaveLength(1);
37
+ * ```
38
+ *
39
+ * @example Intercepting tools
40
+ * ```typescript
41
+ * const { environment, tracker } = createTestEnvironment({
42
+ * interceptTools: { execute: "sandboxed!" },
43
+ * });
44
+ * // When model calls "execute" tool, it gets "sandboxed!" instead of real execution
45
+ * ```
46
+ *
47
+ * @example Transforming model input
48
+ * ```typescript
49
+ * const { environment } = createTestEnvironment({
50
+ * transformInput: (compiled, tools) => ({
51
+ * ...compiled,
52
+ * tools: [], // Remove all tools from model input
53
+ * }),
54
+ * });
55
+ * ```
56
+ */
57
+ export function createTestEnvironment(options = {}) {
58
+ const { name = "test", interceptTools = {}, transformInput, persistData } = options;
59
+ const tracker = {
60
+ initCalls: [],
61
+ prepareModelInputCalls: [],
62
+ toolCalls: [],
63
+ persistCalls: [],
64
+ restoreCalls: [],
65
+ destroyCalls: [],
66
+ reset() {
67
+ this.initCalls = [];
68
+ this.prepareModelInputCalls = [];
69
+ this.toolCalls = [];
70
+ this.persistCalls = [];
71
+ this.restoreCalls = [];
72
+ this.destroyCalls = [];
73
+ },
74
+ };
75
+ const environment = {
76
+ name,
77
+ onSessionInit(session) {
78
+ tracker.initCalls.push(session.id);
79
+ },
80
+ async prepareModelInput(compiled, tools) {
81
+ tracker.prepareModelInputCalls.push({
82
+ tools: tools.map((t) => t.metadata?.name ?? "unknown"),
83
+ });
84
+ if (transformInput) {
85
+ return transformInput(compiled, tools);
86
+ }
87
+ return compiled;
88
+ },
89
+ async executeToolCall(call, tool, next) {
90
+ const interceptor = interceptTools[call.name];
91
+ if (interceptor !== undefined) {
92
+ tracker.toolCalls.push({ name: call.name, intercepted: true });
93
+ if (typeof interceptor === "function") {
94
+ return interceptor(call);
95
+ }
96
+ return {
97
+ id: call.id,
98
+ toolUseId: call.id,
99
+ name: call.name,
100
+ success: true,
101
+ content: [{ type: "text", text: interceptor }],
102
+ };
103
+ }
104
+ tracker.toolCalls.push({ name: call.name, intercepted: false });
105
+ return next();
106
+ },
107
+ onPersist(session, snapshot) {
108
+ tracker.persistCalls.push(session.id);
109
+ if (persistData) {
110
+ return {
111
+ ...snapshot,
112
+ comState: { ...snapshot.comState, ...persistData },
113
+ };
114
+ }
115
+ return snapshot;
116
+ },
117
+ onRestore(session, _snapshot) {
118
+ tracker.restoreCalls.push(session.id);
119
+ },
120
+ onDestroy(session) {
121
+ tracker.destroyCalls.push(session.id);
122
+ },
123
+ };
124
+ return { environment, tracker };
125
+ }
126
+ //# sourceMappingURL=test-environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-environment.js","sourceRoot":"","sources":["../../src/testing/test-environment.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@agentick/core",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Core engine for Agentick",
5
5
  "keywords": [
6
6
  "agent",
7
7
  "ai",
8
8
  "core"
9
9
  ],
10
- "license": "ISC",
10
+ "license": "MIT",
11
11
  "author": "Ryan Lindgren",
12
12
  "repository": {
13
13
  "type": "git",
@@ -1,126 +0,0 @@
1
- /**
2
- * Session Hibernation
3
- *
4
- * Serialize and restore session state for persistence.
5
- *
6
- * Unlike React's hydration (which is about attaching to pre-rendered DOM),
7
- * this is about serializing our state and restoring it later.
8
- *
9
- * Key insight: We don't need to serialize React's fiber tree. We serialize
10
- * OUR state, and React rebuilds its tree from scratch on restore. Since our
11
- * hooks (useData, etc.) read from our caches, the render produces the same
12
- * output as before hibernation.
13
- */
14
- import type { FiberCompiler } from "../compiler/fiber-compiler";
15
- import type { TimelineEntry } from "../hooks/types";
16
- import type { SerializableCacheEntry } from "../hooks/runtime-context";
17
- /**
18
- * Serializable session snapshot.
19
- * This is what gets persisted to storage.
20
- */
21
- export interface SessionSnapshot {
22
- /** Version for migration support */
23
- version: 1;
24
- /** Session ID */
25
- sessionId: string;
26
- /** Current tick number */
27
- tick: number;
28
- /** Conversation timeline */
29
- timeline: SerializableTimelineEntry[];
30
- /** COM state (key-value pairs) */
31
- comState: Record<string, unknown>;
32
- /** Data cache from useData */
33
- dataCache: Record<string, SerializableCacheEntry>;
34
- /** Timestamp when snapshot was taken */
35
- createdAt: string;
36
- /** Optional metadata */
37
- metadata?: Record<string, unknown>;
38
- }
39
- /**
40
- * Timeline entry without non-serializable fields.
41
- */
42
- export interface SerializableTimelineEntry {
43
- id: string;
44
- role: "user" | "assistant" | "system" | "tool";
45
- content: unknown;
46
- createdAt: string;
47
- }
48
- export interface HibernateOptions {
49
- /** Additional metadata to include in snapshot */
50
- metadata?: Record<string, unknown>;
51
- }
52
- /**
53
- * Create a serializable snapshot of the session state.
54
- *
55
- * @example
56
- * ```typescript
57
- * const snapshot = hibernate(compiler, {
58
- * sessionId: session.id,
59
- * tick: session.currentTick,
60
- * timeline: session.timeline,
61
- * comState: session.ctx.state,
62
- * });
63
- *
64
- * // Store snapshot
65
- * await db.sessions.save(session.id, JSON.stringify(snapshot));
66
- * ```
67
- */
68
- export declare function hibernate(compiler: FiberCompiler, state: {
69
- sessionId: string;
70
- tick: number;
71
- timeline: TimelineEntry[];
72
- comState: Map<string, unknown>;
73
- }, options?: HibernateOptions): SessionSnapshot;
74
- export interface HydrateResult {
75
- /** Session ID from snapshot */
76
- sessionId: string;
77
- /** Tick number to resume from */
78
- tick: number;
79
- /** Restored timeline */
80
- timeline: TimelineEntry[];
81
- /** Restored COM state */
82
- comState: Map<string, unknown>;
83
- /** Snapshot metadata */
84
- metadata?: Record<string, unknown>;
85
- /** When the snapshot was created */
86
- snapshotCreatedAt: Date;
87
- }
88
- /**
89
- * Restore session state from a snapshot.
90
- *
91
- * This restores our caches and returns the state to apply to a session.
92
- * The session can then render and React will produce the same output
93
- * because our hooks read from the restored caches.
94
- *
95
- * @example
96
- * ```typescript
97
- * // Load snapshot from storage
98
- * const json = await db.sessions.get(sessionId);
99
- * const snapshot = JSON.parse(json) as SessionSnapshot;
100
- *
101
- * // Create compiler first
102
- * const compiler = new FiberCompiler(ctx);
103
- *
104
- * // Hydrate - restores data cache into compiler
105
- * const state = hydrate(compiler, snapshot);
106
- *
107
- * // Now create/configure session with restored state
108
- * session.timeline = state.timeline;
109
- * session.currentTick = state.tick;
110
- * // etc.
111
- * ```
112
- */
113
- export declare function hydrate(compiler: FiberCompiler, snapshot: SessionSnapshot): HydrateResult;
114
- /**
115
- * Check if a snapshot is valid.
116
- */
117
- export declare function isValidSnapshot(obj: unknown): obj is SessionSnapshot;
118
- /**
119
- * Get snapshot age in milliseconds.
120
- */
121
- export declare function getSnapshotAge(snapshot: SessionSnapshot): number;
122
- /**
123
- * Create a deep clone of a snapshot (for testing/debugging).
124
- */
125
- export declare function cloneSnapshot(snapshot: SessionSnapshot): SessionSnapshot;
126
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hibernation/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAMvE;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,oCAAoC;IACpC,OAAO,EAAE,CAAC,CAAC;IAEX,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;IAElB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IAEb,4BAA4B;IAC5B,QAAQ,EAAE,yBAAyB,EAAE,CAAC;IAEtC,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAElC,8BAA8B;IAC9B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAElD,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAElB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC/C,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,MAAM,WAAW,gBAAgB;IAC/B,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,aAAa,EACvB,KAAK,EAAE;IACL,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,EACD,OAAO,GAAE,gBAAqB,GAC7B,eAAe,CAgBjB;AAMD,MAAM,WAAW,aAAa;IAC5B,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAElB,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IAEb,wBAAwB;IACxB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAE1B,yBAAyB;IACzB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE/B,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEnC,oCAAoC;IACpC,iBAAiB,EAAE,IAAI,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,GAAG,aAAa,CA4BzF;AAMD;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,eAAe,CAapE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAEhE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,eAAe,GAAG,eAAe,CAExE"}
@@ -1,127 +0,0 @@
1
- /**
2
- * Session Hibernation
3
- *
4
- * Serialize and restore session state for persistence.
5
- *
6
- * Unlike React's hydration (which is about attaching to pre-rendered DOM),
7
- * this is about serializing our state and restoring it later.
8
- *
9
- * Key insight: We don't need to serialize React's fiber tree. We serialize
10
- * OUR state, and React rebuilds its tree from scratch on restore. Since our
11
- * hooks (useData, etc.) read from our caches, the render produces the same
12
- * output as before hibernation.
13
- */
14
- /**
15
- * Create a serializable snapshot of the session state.
16
- *
17
- * @example
18
- * ```typescript
19
- * const snapshot = hibernate(compiler, {
20
- * sessionId: session.id,
21
- * tick: session.currentTick,
22
- * timeline: session.timeline,
23
- * comState: session.ctx.state,
24
- * });
25
- *
26
- * // Store snapshot
27
- * await db.sessions.save(session.id, JSON.stringify(snapshot));
28
- * ```
29
- */
30
- export function hibernate(compiler, state, options = {}) {
31
- return {
32
- version: 1,
33
- sessionId: state.sessionId,
34
- tick: state.tick,
35
- timeline: state.timeline.map((entry) => ({
36
- id: entry.id,
37
- role: entry.role,
38
- content: entry.content,
39
- createdAt: entry.createdAt.toISOString(),
40
- })),
41
- comState: Object.fromEntries(state.comState),
42
- dataCache: compiler.getSerializableDataCache(),
43
- createdAt: new Date().toISOString(),
44
- metadata: options.metadata,
45
- };
46
- }
47
- /**
48
- * Restore session state from a snapshot.
49
- *
50
- * This restores our caches and returns the state to apply to a session.
51
- * The session can then render and React will produce the same output
52
- * because our hooks read from the restored caches.
53
- *
54
- * @example
55
- * ```typescript
56
- * // Load snapshot from storage
57
- * const json = await db.sessions.get(sessionId);
58
- * const snapshot = JSON.parse(json) as SessionSnapshot;
59
- *
60
- * // Create compiler first
61
- * const compiler = new FiberCompiler(ctx);
62
- *
63
- * // Hydrate - restores data cache into compiler
64
- * const state = hydrate(compiler, snapshot);
65
- *
66
- * // Now create/configure session with restored state
67
- * session.timeline = state.timeline;
68
- * session.currentTick = state.tick;
69
- * // etc.
70
- * ```
71
- */
72
- export function hydrate(compiler, snapshot) {
73
- // Validate version
74
- if (snapshot.version !== 1) {
75
- throw new Error(`Unsupported snapshot version: ${snapshot.version}`);
76
- }
77
- // Restore data cache into the compiler's runtime store
78
- compiler.setDataCache(snapshot.dataCache);
79
- // Convert timeline dates back
80
- const timeline = snapshot.timeline.map((entry) => ({
81
- id: entry.id,
82
- role: entry.role,
83
- content: entry.content,
84
- createdAt: new Date(entry.createdAt),
85
- }));
86
- // Convert comState back to Map
87
- const comState = new Map(Object.entries(snapshot.comState));
88
- return {
89
- sessionId: snapshot.sessionId,
90
- tick: snapshot.tick,
91
- timeline,
92
- comState,
93
- metadata: snapshot.metadata,
94
- snapshotCreatedAt: new Date(snapshot.createdAt),
95
- };
96
- }
97
- // ============================================================
98
- // Utilities
99
- // ============================================================
100
- /**
101
- * Check if a snapshot is valid.
102
- */
103
- export function isValidSnapshot(obj) {
104
- if (!obj || typeof obj !== "object")
105
- return false;
106
- const s = obj;
107
- return (s.version === 1 &&
108
- typeof s.sessionId === "string" &&
109
- typeof s.tick === "number" &&
110
- Array.isArray(s.timeline) &&
111
- typeof s.comState === "object" &&
112
- typeof s.dataCache === "object" &&
113
- typeof s.createdAt === "string");
114
- }
115
- /**
116
- * Get snapshot age in milliseconds.
117
- */
118
- export function getSnapshotAge(snapshot) {
119
- return Date.now() - new Date(snapshot.createdAt).getTime();
120
- }
121
- /**
122
- * Create a deep clone of a snapshot (for testing/debugging).
123
- */
124
- export function cloneSnapshot(snapshot) {
125
- return JSON.parse(JSON.stringify(snapshot));
126
- }
127
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hibernation/index.ts"],"names":[],"mappings":"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"}