@agentick/core 0.0.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/LICENSE +21 -0
- package/README.md +875 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/.tsbuildinfo.build +1 -0
- package/dist/agent.d.ts +32 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +26 -0
- package/dist/agent.js.map +1 -0
- package/dist/agentick-instance.d.ts +285 -0
- package/dist/agentick-instance.d.ts.map +1 -0
- package/dist/agentick-instance.js +700 -0
- package/dist/agentick-instance.js.map +1 -0
- package/dist/aidk-instance.d.ts +294 -0
- package/dist/aidk-instance.d.ts.map +1 -0
- package/dist/aidk-instance.js +340 -0
- package/dist/aidk-instance.js.map +1 -0
- package/dist/app/session-store.d.ts +57 -0
- package/dist/app/session-store.d.ts.map +1 -0
- package/dist/app/session-store.js +87 -0
- package/dist/app/session-store.js.map +1 -0
- package/dist/app/session.d.ts +209 -0
- package/dist/app/session.d.ts.map +1 -0
- package/dist/app/session.js +2131 -0
- package/dist/app/session.js.map +1 -0
- package/dist/app/sqlite-session-store.d.ts +60 -0
- package/dist/app/sqlite-session-store.d.ts.map +1 -0
- package/dist/app/sqlite-session-store.js +234 -0
- package/dist/app/sqlite-session-store.js.map +1 -0
- package/dist/app/types.d.ts +1461 -0
- package/dist/app/types.d.ts.map +1 -0
- package/dist/app/types.js +14 -0
- package/dist/app/types.js.map +1 -0
- package/dist/app.d.ts +79 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +83 -0
- package/dist/app.js.map +1 -0
- package/dist/channels/adapters/index.d.ts +2 -0
- package/dist/channels/adapters/index.d.ts.map +1 -0
- package/dist/channels/adapters/index.js +2 -0
- package/dist/channels/adapters/index.js.map +1 -0
- package/dist/channels/adapters/redis.d.ts +77 -0
- package/dist/channels/adapters/redis.d.ts.map +1 -0
- package/dist/channels/adapters/redis.js +259 -0
- package/dist/channels/adapters/redis.js.map +1 -0
- package/dist/channels/index.d.ts +38 -0
- package/dist/channels/index.d.ts.map +1 -0
- package/dist/channels/index.js +38 -0
- package/dist/channels/index.js.map +1 -0
- package/dist/channels/service.d.ts +684 -0
- package/dist/channels/service.d.ts.map +1 -0
- package/dist/channels/service.js +870 -0
- package/dist/channels/service.js.map +1 -0
- package/dist/channels/transports/index.d.ts +4 -0
- package/dist/channels/transports/index.d.ts.map +1 -0
- package/dist/channels/transports/index.js +4 -0
- package/dist/channels/transports/index.js.map +1 -0
- package/dist/channels/transports/socketio.d.ts +98 -0
- package/dist/channels/transports/socketio.d.ts.map +1 -0
- package/dist/channels/transports/socketio.js +246 -0
- package/dist/channels/transports/socketio.js.map +1 -0
- package/dist/channels/transports/streamable-http.d.ts +107 -0
- package/dist/channels/transports/streamable-http.d.ts.map +1 -0
- package/dist/channels/transports/streamable-http.js +353 -0
- package/dist/channels/transports/streamable-http.js.map +1 -0
- package/dist/channels/transports/websocket.d.ts +117 -0
- package/dist/channels/transports/websocket.d.ts.map +1 -0
- package/dist/channels/transports/websocket.js +416 -0
- package/dist/channels/transports/websocket.js.map +1 -0
- package/dist/com/index.d.ts +29 -0
- package/dist/com/index.d.ts.map +1 -0
- package/dist/com/index.js +29 -0
- package/dist/com/index.js.map +1 -0
- package/dist/com/object-model.d.ts +634 -0
- package/dist/com/object-model.d.ts.map +1 -0
- package/dist/com/object-model.js +963 -0
- package/dist/com/object-model.js.map +1 -0
- package/dist/com/types.d.ts +192 -0
- package/dist/com/types.d.ts.map +1 -0
- package/dist/com/types.js +1 -0
- package/dist/com/types.js.map +1 -0
- package/dist/compiler/collector.d.ts +16 -0
- package/dist/compiler/collector.d.ts.map +1 -0
- package/dist/compiler/collector.js +388 -0
- package/dist/compiler/collector.js.map +1 -0
- package/dist/compiler/content-block-registry.d.ts +11 -0
- package/dist/compiler/content-block-registry.d.ts.map +1 -0
- package/dist/compiler/content-block-registry.js +312 -0
- package/dist/compiler/content-block-registry.js.map +1 -0
- package/dist/compiler/extractors.d.ts +68 -0
- package/dist/compiler/extractors.d.ts.map +1 -0
- package/dist/compiler/extractors.js +547 -0
- package/dist/compiler/extractors.js.map +1 -0
- package/dist/compiler/fiber-compiler.d.ts +203 -0
- package/dist/compiler/fiber-compiler.d.ts.map +1 -0
- package/dist/compiler/fiber-compiler.js +498 -0
- package/dist/compiler/fiber-compiler.js.map +1 -0
- package/dist/compiler/fiber.d.ts +61 -0
- package/dist/compiler/fiber.d.ts.map +1 -0
- package/dist/compiler/fiber.js +244 -0
- package/dist/compiler/fiber.js.map +1 -0
- package/dist/compiler/index.d.ts +18 -0
- package/dist/compiler/index.d.ts.map +1 -0
- package/dist/compiler/index.js +38 -0
- package/dist/compiler/index.js.map +1 -0
- package/dist/compiler/scheduler.d.ts +95 -0
- package/dist/compiler/scheduler.d.ts.map +1 -0
- package/dist/compiler/scheduler.js +138 -0
- package/dist/compiler/scheduler.js.map +1 -0
- package/dist/compiler/structure-renderer.d.ts +42 -0
- package/dist/compiler/structure-renderer.d.ts.map +1 -0
- package/dist/compiler/structure-renderer.js +189 -0
- package/dist/compiler/structure-renderer.js.map +1 -0
- package/dist/compiler/types.d.ts +96 -0
- package/dist/compiler/types.d.ts.map +1 -0
- package/dist/compiler/types.js +19 -0
- package/dist/compiler/types.js.map +1 -0
- package/dist/component/component-hooks.d.ts +68 -0
- package/dist/component/component-hooks.d.ts.map +1 -0
- package/dist/component/component-hooks.js +112 -0
- package/dist/component/component-hooks.js.map +1 -0
- package/dist/component/component.d.ts +314 -0
- package/dist/component/component.d.ts.map +1 -0
- package/dist/component/component.js +64 -0
- package/dist/component/component.js.map +1 -0
- package/dist/component/index.d.ts +47 -0
- package/dist/component/index.d.ts.map +1 -0
- package/dist/component/index.js +47 -0
- package/dist/component/index.js.map +1 -0
- package/dist/component/tentickle-component.d.ts +185 -0
- package/dist/component/tentickle-component.d.ts.map +1 -0
- package/dist/component/tentickle-component.js +182 -0
- package/dist/component/tentickle-component.js.map +1 -0
- package/dist/content/index.d.ts +12 -0
- package/dist/content/index.d.ts.map +1 -0
- package/dist/content/index.js +17 -0
- package/dist/content/index.js.map +1 -0
- package/dist/context/index.d.ts +51 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +69 -0
- package/dist/context/index.js.map +1 -0
- package/dist/core/channel-helpers.d.ts +31 -0
- package/dist/core/channel-helpers.d.ts.map +1 -0
- package/dist/core/channel-helpers.js +62 -0
- package/dist/core/channel-helpers.js.map +1 -0
- package/dist/core/channel.d.ts +164 -0
- package/dist/core/channel.d.ts.map +1 -0
- package/dist/core/channel.js +199 -0
- package/dist/core/channel.js.map +1 -0
- package/dist/core/context.d.ts +412 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +290 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/event-buffer.d.ts +212 -0
- package/dist/core/event-buffer.d.ts.map +1 -0
- package/dist/core/event-buffer.js +346 -0
- package/dist/core/event-buffer.js.map +1 -0
- package/dist/core/execution-helpers.d.ts +179 -0
- package/dist/core/execution-helpers.d.ts.map +1 -0
- package/dist/core/execution-helpers.js +212 -0
- package/dist/core/execution-helpers.js.map +1 -0
- package/dist/core/execution-tracker.d.ts +53 -0
- package/dist/core/execution-tracker.d.ts.map +1 -0
- package/dist/core/execution-tracker.js +309 -0
- package/dist/core/execution-tracker.js.map +1 -0
- package/dist/core/index.d.ts +58 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +58 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/logger.d.ts +341 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +346 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/metrics-helpers.d.ts +40 -0
- package/dist/core/metrics-helpers.d.ts.map +1 -0
- package/dist/core/metrics-helpers.js +72 -0
- package/dist/core/metrics-helpers.js.map +1 -0
- package/dist/core/otel-provider.d.ts +54 -0
- package/dist/core/otel-provider.d.ts.map +1 -0
- package/dist/core/otel-provider.js +107 -0
- package/dist/core/otel-provider.js.map +1 -0
- package/dist/core/procedure-graph.d.ts +136 -0
- package/dist/core/procedure-graph.d.ts.map +1 -0
- package/dist/core/procedure-graph.js +272 -0
- package/dist/core/procedure-graph.js.map +1 -0
- package/dist/core/procedure.d.ts +755 -0
- package/dist/core/procedure.d.ts.map +1 -0
- package/dist/core/procedure.js +899 -0
- package/dist/core/procedure.js.map +1 -0
- package/dist/core/stream.d.ts +106 -0
- package/dist/core/stream.d.ts.map +1 -0
- package/dist/core/stream.js +186 -0
- package/dist/core/stream.js.map +1 -0
- package/dist/core/telemetry.d.ts +182 -0
- package/dist/core/telemetry.d.ts.map +1 -0
- package/dist/core/telemetry.js +124 -0
- package/dist/core/telemetry.js.map +1 -0
- package/dist/engine/client-tool-coordinator.d.ts +50 -0
- package/dist/engine/client-tool-coordinator.d.ts.map +1 -0
- package/dist/engine/client-tool-coordinator.js +121 -0
- package/dist/engine/client-tool-coordinator.js.map +1 -0
- package/dist/engine/engine-events.d.ts +117 -0
- package/dist/engine/engine-events.d.ts.map +1 -0
- package/dist/engine/engine-events.js +178 -0
- package/dist/engine/engine-events.js.map +1 -0
- package/dist/engine/engine-response.d.ts +48 -0
- package/dist/engine/engine-response.d.ts.map +1 -0
- package/dist/engine/engine-response.js +2 -0
- package/dist/engine/engine-response.js.map +1 -0
- package/dist/engine/execution-graph.d.ts +104 -0
- package/dist/engine/execution-graph.d.ts.map +1 -0
- package/dist/engine/execution-graph.js +257 -0
- package/dist/engine/execution-graph.js.map +1 -0
- package/dist/engine/execution-handle.d.ts +212 -0
- package/dist/engine/execution-handle.d.ts.map +1 -0
- package/dist/engine/execution-handle.js +602 -0
- package/dist/engine/execution-handle.js.map +1 -0
- package/dist/engine/execution-types.d.ts +248 -0
- package/dist/engine/execution-types.d.ts.map +1 -0
- package/dist/engine/execution-types.js +23 -0
- package/dist/engine/execution-types.js.map +1 -0
- package/dist/engine/index.d.ts +21 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +23 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/tool-confirmation-coordinator.d.ts +74 -0
- package/dist/engine/tool-confirmation-coordinator.d.ts.map +1 -0
- package/dist/engine/tool-confirmation-coordinator.js +137 -0
- package/dist/engine/tool-confirmation-coordinator.js.map +1 -0
- package/dist/engine/tool-executor.d.ts +127 -0
- package/dist/engine/tool-executor.d.ts.map +1 -0
- package/dist/engine/tool-executor.js +363 -0
- package/dist/engine/tool-executor.js.map +1 -0
- package/dist/hibernation/index.d.ts +126 -0
- package/dist/hibernation/index.d.ts.map +1 -0
- package/dist/hibernation/index.js +127 -0
- package/dist/hibernation/index.js.map +1 -0
- package/dist/hooks/base-hook-registry.d.ts +41 -0
- package/dist/hooks/base-hook-registry.d.ts.map +1 -0
- package/dist/hooks/base-hook-registry.js +76 -0
- package/dist/hooks/base-hook-registry.js.map +1 -0
- package/dist/hooks/com-state.d.ts +40 -0
- package/dist/hooks/com-state.d.ts.map +1 -0
- package/dist/hooks/com-state.js +90 -0
- package/dist/hooks/com-state.js.map +1 -0
- package/dist/hooks/context-info.d.ts +139 -0
- package/dist/hooks/context-info.d.ts.map +1 -0
- package/dist/hooks/context-info.js +115 -0
- package/dist/hooks/context-info.js.map +1 -0
- package/dist/hooks/context-internal.d.ts +21 -0
- package/dist/hooks/context-internal.d.ts.map +1 -0
- package/dist/hooks/context-internal.js +20 -0
- package/dist/hooks/context-internal.js.map +1 -0
- package/dist/hooks/context.d.ts +64 -0
- package/dist/hooks/context.d.ts.map +1 -0
- package/dist/hooks/context.js +83 -0
- package/dist/hooks/context.js.map +1 -0
- package/dist/hooks/data.d.ts +33 -0
- package/dist/hooks/data.d.ts.map +1 -0
- package/dist/hooks/data.js +84 -0
- package/dist/hooks/data.js.map +1 -0
- package/dist/hooks/formatter-context.d.ts +34 -0
- package/dist/hooks/formatter-context.d.ts.map +1 -0
- package/dist/hooks/formatter-context.js +34 -0
- package/dist/hooks/formatter-context.js.map +1 -0
- package/dist/hooks/hook-registry.d.ts +45 -0
- package/dist/hooks/hook-registry.d.ts.map +1 -0
- package/dist/hooks/hook-registry.js +109 -0
- package/dist/hooks/hook-registry.js.map +1 -0
- package/dist/hooks/index.d.ts +20 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +47 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/knob.d.ts +87 -0
- package/dist/hooks/knob.d.ts.map +1 -0
- package/dist/hooks/knob.js +129 -0
- package/dist/hooks/knob.js.map +1 -0
- package/dist/hooks/knobs-component.d.ts +70 -0
- package/dist/hooks/knobs-component.d.ts.map +1 -0
- package/dist/hooks/knobs-component.js +300 -0
- package/dist/hooks/knobs-component.js.map +1 -0
- package/dist/hooks/lifecycle.d.ts +158 -0
- package/dist/hooks/lifecycle.d.ts.map +1 -0
- package/dist/hooks/lifecycle.js +217 -0
- package/dist/hooks/lifecycle.js.map +1 -0
- package/dist/hooks/message-context.d.ts +101 -0
- package/dist/hooks/message-context.d.ts.map +1 -0
- package/dist/hooks/message-context.js +145 -0
- package/dist/hooks/message-context.js.map +1 -0
- package/dist/hooks/policy-context.d.ts.map +1 -0
- package/dist/hooks/runtime-context.d.ts +122 -0
- package/dist/hooks/runtime-context.d.ts.map +1 -0
- package/dist/hooks/runtime-context.js +149 -0
- package/dist/hooks/runtime-context.js.map +1 -0
- package/dist/hooks/signal.d.ts +267 -0
- package/dist/hooks/signal.d.ts.map +1 -0
- package/dist/hooks/signal.js +825 -0
- package/dist/hooks/signal.js.map +1 -0
- package/dist/hooks/types.d.ts +179 -0
- package/dist/hooks/types.d.ts.map +1 -0
- package/dist/hooks/types.js +5 -0
- package/dist/hooks/types.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx/components/agent.d.ts +64 -0
- package/dist/jsx/components/agent.d.ts.map +1 -0
- package/dist/jsx/components/agent.js +80 -0
- package/dist/jsx/components/agent.js.map +1 -0
- package/dist/jsx/components/complete.d.ts +65 -0
- package/dist/jsx/components/complete.d.ts.map +1 -0
- package/dist/jsx/components/complete.js +64 -0
- package/dist/jsx/components/complete.js.map +1 -0
- package/dist/jsx/components/content.d.ts +98 -0
- package/dist/jsx/components/content.d.ts.map +1 -0
- package/dist/jsx/components/content.js +51 -0
- package/dist/jsx/components/content.js.map +1 -0
- package/dist/jsx/components/harness.d.ts +118 -0
- package/dist/jsx/components/harness.d.ts.map +1 -0
- package/dist/jsx/components/harness.js +117 -0
- package/dist/jsx/components/harness.js.map +1 -0
- package/dist/jsx/components/index.d.ts +11 -0
- package/dist/jsx/components/index.d.ts.map +1 -0
- package/dist/jsx/components/index.js +11 -0
- package/dist/jsx/components/index.js.map +1 -0
- package/dist/jsx/components/markdown.d.ts +31 -0
- package/dist/jsx/components/markdown.d.ts.map +1 -0
- package/dist/jsx/components/markdown.js +17 -0
- package/dist/jsx/components/markdown.js.map +1 -0
- package/dist/jsx/components/messages.d.ts +283 -0
- package/dist/jsx/components/messages.d.ts.map +1 -0
- package/dist/jsx/components/messages.js +257 -0
- package/dist/jsx/components/messages.js.map +1 -0
- package/dist/jsx/components/model.d.ts +94 -0
- package/dist/jsx/components/model.d.ts.map +1 -0
- package/dist/jsx/components/model.js +96 -0
- package/dist/jsx/components/model.js.map +1 -0
- package/dist/jsx/components/primitives.d.ts +117 -0
- package/dist/jsx/components/primitives.d.ts.map +1 -0
- package/dist/jsx/components/primitives.js +83 -0
- package/dist/jsx/components/primitives.js.map +1 -0
- package/dist/jsx/components/renderer.d.ts +24 -0
- package/dist/jsx/components/renderer.d.ts.map +1 -0
- package/dist/jsx/components/renderer.js +11 -0
- package/dist/jsx/components/renderer.js.map +1 -0
- package/dist/jsx/components/semantic.d.ts +155 -0
- package/dist/jsx/components/semantic.d.ts.map +1 -0
- package/dist/jsx/components/semantic.js +39 -0
- package/dist/jsx/components/semantic.js.map +1 -0
- package/dist/jsx/components/timeline.d.ts +157 -0
- package/dist/jsx/components/timeline.d.ts.map +1 -0
- package/dist/jsx/components/timeline.js +357 -0
- package/dist/jsx/components/timeline.js.map +1 -0
- package/dist/jsx/components/token-budget.d.ts +70 -0
- package/dist/jsx/components/token-budget.d.ts.map +1 -0
- package/dist/jsx/components/token-budget.js +135 -0
- package/dist/jsx/components/token-budget.js.map +1 -0
- package/dist/jsx/components/xml.d.ts +27 -0
- package/dist/jsx/components/xml.d.ts.map +1 -0
- package/dist/jsx/components/xml.js +17 -0
- package/dist/jsx/components/xml.js.map +1 -0
- package/dist/jsx/index.d.ts +58 -0
- package/dist/jsx/index.d.ts.map +1 -0
- package/dist/jsx/index.js +59 -0
- package/dist/jsx/index.js.map +1 -0
- package/dist/jsx/jsx-runtime.d.ts +370 -0
- package/dist/jsx/jsx-runtime.d.ts.map +1 -0
- package/dist/jsx/jsx-runtime.js +79 -0
- package/dist/jsx/jsx-runtime.js.map +1 -0
- package/dist/jsx/jsx-types.d.ts +23 -0
- package/dist/jsx/jsx-types.d.ts.map +1 -0
- package/dist/jsx/jsx-types.js +1 -0
- package/dist/jsx/jsx-types.js.map +1 -0
- package/dist/mcp/client.d.ts +46 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +138 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/component.d.ts +95 -0
- package/dist/mcp/component.d.ts.map +1 -0
- package/dist/mcp/component.js +185 -0
- package/dist/mcp/component.js.map +1 -0
- package/dist/mcp/create-mcp-tool.d.ts +191 -0
- package/dist/mcp/create-mcp-tool.d.ts.map +1 -0
- package/dist/mcp/create-mcp-tool.js +228 -0
- package/dist/mcp/create-mcp-tool.js.map +1 -0
- package/dist/mcp/index.d.ts +49 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +48 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/service.d.ts +39 -0
- package/dist/mcp/service.d.ts.map +1 -0
- package/dist/mcp/service.js +77 -0
- package/dist/mcp/service.js.map +1 -0
- package/dist/mcp/tool.d.ts +55 -0
- package/dist/mcp/tool.d.ts.map +1 -0
- package/dist/mcp/tool.js +119 -0
- package/dist/mcp/tool.js.map +1 -0
- package/dist/mcp/types.d.ts +72 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +6 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/middleware/defaults.d.ts +9 -0
- package/dist/middleware/defaults.d.ts.map +1 -0
- package/dist/middleware/defaults.js +47 -0
- package/dist/middleware/defaults.js.map +1 -0
- package/dist/model/adapter-helpers.d.ts +161 -0
- package/dist/model/adapter-helpers.d.ts.map +1 -0
- package/dist/model/adapter-helpers.js +351 -0
- package/dist/model/adapter-helpers.js.map +1 -0
- package/dist/model/adapter.d.ts +399 -0
- package/dist/model/adapter.d.ts.map +1 -0
- package/dist/model/adapter.js +497 -0
- package/dist/model/adapter.js.map +1 -0
- package/dist/model/index.d.ts +54 -0
- package/dist/model/index.d.ts.map +1 -0
- package/dist/model/index.js +55 -0
- package/dist/model/index.js.map +1 -0
- package/dist/model/model-hooks.d.ts +45 -0
- package/dist/model/model-hooks.d.ts.map +1 -0
- package/dist/model/model-hooks.js +24 -0
- package/dist/model/model-hooks.js.map +1 -0
- package/dist/model/model.d.ts +302 -0
- package/dist/model/model.d.ts.map +1 -0
- package/dist/model/model.js +20 -0
- package/dist/model/model.js.map +1 -0
- package/dist/model/simple-adapter.d.ts +176 -0
- package/dist/model/simple-adapter.d.ts.map +1 -0
- package/dist/model/simple-adapter.js +264 -0
- package/dist/model/simple-adapter.js.map +1 -0
- package/dist/model/stream-accumulator.d.ts +284 -0
- package/dist/model/stream-accumulator.d.ts.map +1 -0
- package/dist/model/stream-accumulator.js +532 -0
- package/dist/model/stream-accumulator.js.map +1 -0
- package/dist/model/utils/index.d.ts +2 -0
- package/dist/model/utils/index.d.ts.map +1 -0
- package/dist/model/utils/index.js +2 -0
- package/dist/model/utils/index.js.map +1 -0
- package/dist/model/utils/language-model.d.ts +26 -0
- package/dist/model/utils/language-model.d.ts.map +1 -0
- package/dist/model/utils/language-model.js +706 -0
- package/dist/model/utils/language-model.js.map +1 -0
- package/dist/procedure/index.d.ts +20 -0
- package/dist/procedure/index.d.ts.map +1 -0
- package/dist/procedure/index.js +19 -0
- package/dist/procedure/index.js.map +1 -0
- package/dist/reconciler/devtools-bridge.d.ts +40 -0
- package/dist/reconciler/devtools-bridge.d.ts.map +1 -0
- package/dist/reconciler/devtools-bridge.js +79 -0
- package/dist/reconciler/devtools-bridge.js.map +1 -0
- package/dist/reconciler/host-config.d.ts +39 -0
- package/dist/reconciler/host-config.d.ts.map +1 -0
- package/dist/reconciler/host-config.js +195 -0
- package/dist/reconciler/host-config.js.map +1 -0
- package/dist/reconciler/index.d.ts +7 -0
- package/dist/reconciler/index.d.ts.map +1 -0
- package/dist/reconciler/index.js +7 -0
- package/dist/reconciler/index.js.map +1 -0
- package/dist/reconciler/reconciler.d.ts +47 -0
- package/dist/reconciler/reconciler.d.ts.map +1 -0
- package/dist/reconciler/reconciler.js +89 -0
- package/dist/reconciler/reconciler.js.map +1 -0
- package/dist/reconciler/types.d.ts +86 -0
- package/dist/reconciler/types.d.ts.map +1 -0
- package/dist/reconciler/types.js +37 -0
- package/dist/reconciler/types.js.map +1 -0
- package/dist/renderers/base.d.ts +98 -0
- package/dist/renderers/base.d.ts.map +1 -0
- package/dist/renderers/base.js +82 -0
- package/dist/renderers/base.js.map +1 -0
- package/dist/renderers/index.d.ts +31 -0
- package/dist/renderers/index.d.ts.map +1 -0
- package/dist/renderers/index.js +31 -0
- package/dist/renderers/index.js.map +1 -0
- package/dist/renderers/markdown.d.ts +48 -0
- package/dist/renderers/markdown.d.ts.map +1 -0
- package/dist/renderers/markdown.js +432 -0
- package/dist/renderers/markdown.js.map +1 -0
- package/dist/renderers/types.d.ts +7 -0
- package/dist/renderers/types.d.ts.map +1 -0
- package/dist/renderers/types.js +7 -0
- package/dist/renderers/types.js.map +1 -0
- package/dist/renderers/xml.d.ts +49 -0
- package/dist/renderers/xml.d.ts.map +1 -0
- package/dist/renderers/xml.js +444 -0
- package/dist/renderers/xml.js.map +1 -0
- package/dist/state/boundary.d.ts +347 -0
- package/dist/state/boundary.d.ts.map +1 -0
- package/dist/state/boundary.js +341 -0
- package/dist/state/boundary.js.map +1 -0
- package/dist/state/context.d.ts +138 -0
- package/dist/state/context.d.ts.map +1 -0
- package/dist/state/context.js +139 -0
- package/dist/state/context.js.map +1 -0
- package/dist/state/hooks.d.ts +798 -0
- package/dist/state/hooks.d.ts.map +1 -0
- package/dist/state/hooks.js +1437 -0
- package/dist/state/hooks.js.map +1 -0
- package/dist/state/index.d.ts +72 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +73 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/signal.d.ts +223 -0
- package/dist/state/signal.d.ts.map +1 -0
- package/dist/state/signal.js +699 -0
- package/dist/state/signal.js.map +1 -0
- package/dist/state/use-state.d.ts +210 -0
- package/dist/state/use-state.d.ts.map +1 -0
- package/dist/state/use-state.js +327 -0
- package/dist/state/use-state.js.map +1 -0
- package/dist/tentickle-instance.d.ts +285 -0
- package/dist/tentickle-instance.d.ts.map +1 -0
- package/dist/tentickle-instance.js +700 -0
- package/dist/tentickle-instance.js.map +1 -0
- package/dist/testing/act.d.ts +59 -0
- package/dist/testing/act.d.ts.map +1 -0
- package/dist/testing/act.js +92 -0
- package/dist/testing/act.js.map +1 -0
- package/dist/testing/async-helpers.d.ts +99 -0
- package/dist/testing/async-helpers.d.ts.map +1 -0
- package/dist/testing/async-helpers.js +193 -0
- package/dist/testing/async-helpers.js.map +1 -0
- package/dist/testing/compile-agent.d.ts +101 -0
- package/dist/testing/compile-agent.d.ts.map +1 -0
- package/dist/testing/compile-agent.js +136 -0
- package/dist/testing/compile-agent.js.map +1 -0
- package/dist/testing/index.d.ts +57 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +59 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/mock-app.d.ts +163 -0
- package/dist/testing/mock-app.d.ts.map +1 -0
- package/dist/testing/mock-app.js +393 -0
- package/dist/testing/mock-app.js.map +1 -0
- package/dist/testing/mocks.d.ts +142 -0
- package/dist/testing/mocks.d.ts.map +1 -0
- package/dist/testing/mocks.js +191 -0
- package/dist/testing/mocks.js.map +1 -0
- package/dist/testing/render-agent.d.ts +146 -0
- package/dist/testing/render-agent.d.ts.map +1 -0
- package/dist/testing/render-agent.js +200 -0
- package/dist/testing/render-agent.js.map +1 -0
- package/dist/testing/test-adapter.d.ts +157 -0
- package/dist/testing/test-adapter.d.ts.map +1 -0
- package/dist/testing/test-adapter.js +297 -0
- package/dist/testing/test-adapter.js.map +1 -0
- package/dist/testing/test-model.d.ts +132 -0
- package/dist/testing/test-model.d.ts.map +1 -0
- package/dist/testing/test-model.js +260 -0
- package/dist/testing/test-model.js.map +1 -0
- package/dist/tool/index.d.ts +61 -0
- package/dist/tool/index.d.ts.map +1 -0
- package/dist/tool/index.js +63 -0
- package/dist/tool/index.js.map +1 -0
- package/dist/tool/tool-hooks.d.ts +45 -0
- package/dist/tool/tool-hooks.d.ts.map +1 -0
- package/dist/tool/tool-hooks.js +35 -0
- package/dist/tool/tool-hooks.js.map +1 -0
- package/dist/tool/tool.d.ts +403 -0
- package/dist/tool/tool.d.ts.map +1 -0
- package/dist/tool/tool.js +176 -0
- package/dist/tool/tool.js.map +1 -0
- package/dist/types.d.ts +442 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +97 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/abort-utils.d.ts +5 -0
- package/dist/utils/abort-utils.d.ts.map +1 -0
- package/dist/utils/abort-utils.js +50 -0
- package/dist/utils/abort-utils.js.map +1 -0
- package/dist/utils/classify-error.d.ts +19 -0
- package/dist/utils/classify-error.d.ts.map +1 -0
- package/dist/utils/classify-error.js +77 -0
- package/dist/utils/classify-error.js.map +1 -0
- package/dist/utils/index.d.ts +21 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +21 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/normalization.d.ts +6 -0
- package/dist/utils/normalization.d.ts.map +1 -0
- package/dist/utils/normalization.js +103 -0
- package/dist/utils/normalization.js.map +1 -0
- package/dist/utils/registry.d.ts +15 -0
- package/dist/utils/registry.d.ts.map +1 -0
- package/dist/utils/registry.js +28 -0
- package/dist/utils/registry.js.map +1 -0
- package/dist/utils/schema.d.ts +7 -0
- package/dist/utils/schema.d.ts.map +1 -0
- package/dist/utils/schema.js +13 -0
- package/dist/utils/schema.js.map +1 -0
- package/dist/utils/token-estimate.d.ts +87 -0
- package/dist/utils/token-estimate.d.ts.map +1 -0
- package/dist/utils/token-estimate.js +199 -0
- package/dist/utils/token-estimate.js.map +1 -0
- package/dist/v2/reconciler/host-config.d.ts +31 -0
- package/dist/v2/reconciler/host-config.d.ts.map +1 -0
- package/dist/v2/reconciler/host-config.js +197 -0
- package/dist/v2/reconciler/host-config.js.map +1 -0
- package/dist/v2/reconciler/index.d.ts +7 -0
- package/dist/v2/reconciler/index.d.ts.map +1 -0
- package/dist/v2/reconciler/index.js +7 -0
- package/dist/v2/reconciler/index.js.map +1 -0
- package/dist/v2/reconciler/reconciler.d.ts +39 -0
- package/dist/v2/reconciler/reconciler.d.ts.map +1 -0
- package/dist/v2/reconciler/reconciler.js +54 -0
- package/dist/v2/reconciler/reconciler.js.map +1 -0
- package/dist/v2/reconciler/types.d.ts +64 -0
- package/dist/v2/reconciler/types.d.ts.map +1 -0
- package/dist/v2/reconciler/types.js +20 -0
- package/dist/v2/reconciler/types.js.map +1 -0
- package/dist/v2/renderers/index.d.ts +7 -0
- package/dist/v2/renderers/index.d.ts.map +1 -0
- package/dist/v2/renderers/index.js +7 -0
- package/dist/v2/renderers/index.js.map +1 -0
- package/dist/v2/renderers/markdown.d.ts +16 -0
- package/dist/v2/renderers/markdown.d.ts.map +1 -0
- package/dist/v2/renderers/markdown.js +65 -0
- package/dist/v2/renderers/markdown.js.map +1 -0
- package/dist/v2/renderers/types.d.ts +26 -0
- package/dist/v2/renderers/types.d.ts.map +1 -0
- package/dist/v2/renderers/types.js +6 -0
- package/dist/v2/renderers/types.js.map +1 -0
- package/dist/v2/renderers/xml.d.ts +17 -0
- package/dist/v2/renderers/xml.d.ts.map +1 -0
- package/dist/v2/renderers/xml.js +73 -0
- package/dist/v2/renderers/xml.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,825 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Signal implementation for reactive state management.
|
|
3
|
+
*
|
|
4
|
+
* Signals provide a lightweight, framework-agnostic way to manage reactive state.
|
|
5
|
+
* Similar to Angular/SolidJS signals.
|
|
6
|
+
*
|
|
7
|
+
* This is the full signal library with:
|
|
8
|
+
* - AsyncLocalStorage for concurrency safety
|
|
9
|
+
* - Auto-tracking computed signals
|
|
10
|
+
* - Batch operations
|
|
11
|
+
* - COM state integration
|
|
12
|
+
* - Compiler integration for automatic recompilation
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* // Create a signal
|
|
17
|
+
* const count = signal(0);
|
|
18
|
+
*
|
|
19
|
+
* // Read value
|
|
20
|
+
* console.log(count()); // 0
|
|
21
|
+
*
|
|
22
|
+
* // Update value
|
|
23
|
+
* count.set(10);
|
|
24
|
+
* console.log(count()); // 10
|
|
25
|
+
*
|
|
26
|
+
* // Update with function
|
|
27
|
+
* count.update(n => n + 1);
|
|
28
|
+
* console.log(count()); // 11
|
|
29
|
+
*
|
|
30
|
+
* // Computed signal (memoized, auto-updates)
|
|
31
|
+
* const doubled = computed(() => count() * 2);
|
|
32
|
+
* console.log(doubled()); // 22
|
|
33
|
+
*
|
|
34
|
+
* // Cleanup when done
|
|
35
|
+
* count.dispose();
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @see docs/state-management.md for full documentation
|
|
39
|
+
*/
|
|
40
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
41
|
+
import { useRef, useState, useEffect, useContext, useDebugValue } from "react";
|
|
42
|
+
import { COMContext } from "./context";
|
|
43
|
+
// Import for render phase detection
|
|
44
|
+
import { isCompilerRendering, shouldSkipRecompile, getActiveCompiler, } from "../compiler/fiber-compiler";
|
|
45
|
+
/**
|
|
46
|
+
* SignalContext holds per-execution state for signals.
|
|
47
|
+
*
|
|
48
|
+
* While batch() and computed() are synchronous operations that complete
|
|
49
|
+
* without yielding to the event loop, using AsyncLocalStorage provides:
|
|
50
|
+
*
|
|
51
|
+
* 1. **Defensive design** - If async code is ever introduced in batch/computed,
|
|
52
|
+
* it won't break.
|
|
53
|
+
* 2. **Explicit isolation** - Each Agentick execution has its own context,
|
|
54
|
+
* making the concurrency model clear.
|
|
55
|
+
* 3. **Consistency** - Same pattern as RenderContext.scheduleWork.
|
|
56
|
+
*
|
|
57
|
+
* Note: In current usage, batch/tracking are synchronous, so the global
|
|
58
|
+
* fallback works identically to ALS for single-execution scenarios.
|
|
59
|
+
*/
|
|
60
|
+
class SignalContext {
|
|
61
|
+
/** Stack of tracking contexts for computed/effect dependency tracking */
|
|
62
|
+
trackingStack = [];
|
|
63
|
+
/** Current batch nesting depth */
|
|
64
|
+
batchDepth = 0;
|
|
65
|
+
/** Effects waiting to be flushed after batch completes */
|
|
66
|
+
pendingEffects = new Set();
|
|
67
|
+
/** Whether a microtask flush is scheduled */
|
|
68
|
+
flushScheduled = false;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* AsyncLocalStorage for signal execution context.
|
|
72
|
+
* Each Agentick execution (app.run, session.tick) runs within its own context.
|
|
73
|
+
*/
|
|
74
|
+
const signalContextStorage = new AsyncLocalStorage();
|
|
75
|
+
/**
|
|
76
|
+
* Global fallback context for signals used outside of Agentick execution.
|
|
77
|
+
* This allows standalone signal usage (e.g., in tests, scripts) while
|
|
78
|
+
* maintaining full concurrency safety within Agentick.
|
|
79
|
+
*/
|
|
80
|
+
const globalSignalContext = new SignalContext();
|
|
81
|
+
/**
|
|
82
|
+
* Get the current signal context.
|
|
83
|
+
* Returns the ALS context if available, otherwise the global fallback.
|
|
84
|
+
*/
|
|
85
|
+
function getSignalContext() {
|
|
86
|
+
return signalContextStorage.getStore() ?? globalSignalContext;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Run a function within a signal context.
|
|
90
|
+
* Used by FiberCompiler to establish per-execution context.
|
|
91
|
+
*
|
|
92
|
+
* @internal
|
|
93
|
+
*/
|
|
94
|
+
export function runWithSignalContext(fn) {
|
|
95
|
+
return signalContextStorage.run(new SignalContext(), fn);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Run an async function within a signal context.
|
|
99
|
+
* Used by FiberCompiler to establish per-execution context.
|
|
100
|
+
*
|
|
101
|
+
* @internal
|
|
102
|
+
*/
|
|
103
|
+
export async function runWithSignalContextAsync(fn) {
|
|
104
|
+
return signalContextStorage.run(new SignalContext(), fn);
|
|
105
|
+
}
|
|
106
|
+
// ============================================================================
|
|
107
|
+
// Types
|
|
108
|
+
// ============================================================================
|
|
109
|
+
export const SIGNAL_SYMBOL = Symbol.for("agentick.signal");
|
|
110
|
+
export const COMPUTED_SYMBOL = Symbol.for("agentick.computed");
|
|
111
|
+
export const EFFECT_SYMBOL = Symbol.for("agentick.effect");
|
|
112
|
+
// ============================================================================
|
|
113
|
+
// Batching
|
|
114
|
+
// ============================================================================
|
|
115
|
+
/**
|
|
116
|
+
* Batch multiple signal updates together.
|
|
117
|
+
* Effects only run once after all updates complete.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```typescript
|
|
121
|
+
* batch(() => {
|
|
122
|
+
* count.set(1);
|
|
123
|
+
* name.set('Alice');
|
|
124
|
+
* // Effects run once here, not twice
|
|
125
|
+
* });
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
export function batch(fn) {
|
|
129
|
+
const ctx = getSignalContext();
|
|
130
|
+
ctx.batchDepth++;
|
|
131
|
+
try {
|
|
132
|
+
return fn();
|
|
133
|
+
}
|
|
134
|
+
finally {
|
|
135
|
+
ctx.batchDepth--;
|
|
136
|
+
if (ctx.batchDepth === 0) {
|
|
137
|
+
flushPendingEffects(ctx);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function scheduleEffect(effectFn) {
|
|
142
|
+
const ctx = getSignalContext();
|
|
143
|
+
if (ctx.batchDepth > 0) {
|
|
144
|
+
ctx.pendingEffects.add(effectFn);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
// Schedule microtask flush if not already scheduled
|
|
148
|
+
ctx.pendingEffects.add(effectFn);
|
|
149
|
+
if (!ctx.flushScheduled) {
|
|
150
|
+
ctx.flushScheduled = true;
|
|
151
|
+
// Capture context for the microtask
|
|
152
|
+
queueMicrotask(() => flushPendingEffects(ctx));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function flushPendingEffects(ctx) {
|
|
156
|
+
ctx.flushScheduled = false;
|
|
157
|
+
const effects = [...ctx.pendingEffects];
|
|
158
|
+
ctx.pendingEffects.clear();
|
|
159
|
+
for (const effectFn of effects) {
|
|
160
|
+
try {
|
|
161
|
+
effectFn();
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
console.error("Error in signal effect:", error);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function getCurrentTrackingContext() {
|
|
169
|
+
const ctx = getSignalContext();
|
|
170
|
+
return ctx.trackingStack[ctx.trackingStack.length - 1];
|
|
171
|
+
}
|
|
172
|
+
function pushTrackingContext(trackingCtx) {
|
|
173
|
+
const ctx = getSignalContext();
|
|
174
|
+
ctx.trackingStack.push(trackingCtx);
|
|
175
|
+
}
|
|
176
|
+
function popTrackingContext() {
|
|
177
|
+
const ctx = getSignalContext();
|
|
178
|
+
ctx.trackingStack.pop();
|
|
179
|
+
}
|
|
180
|
+
// ============================================================================
|
|
181
|
+
// Signal (standalone)
|
|
182
|
+
// ============================================================================
|
|
183
|
+
/**
|
|
184
|
+
* Creates a writable signal with an initial value.
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```typescript
|
|
188
|
+
* const count = signal(0);
|
|
189
|
+
* count(); // 0
|
|
190
|
+
* count.set(10); // set to 10
|
|
191
|
+
* count.update(n => n + 1); // increment
|
|
192
|
+
* count.dispose(); // cleanup
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
export function signal(initialValue, options) {
|
|
196
|
+
let value = initialValue;
|
|
197
|
+
let isDisposed = false;
|
|
198
|
+
const subscriptions = new Set();
|
|
199
|
+
const equal = options?.equal ?? Object.is;
|
|
200
|
+
const notify = () => {
|
|
201
|
+
for (const sub of subscriptions) {
|
|
202
|
+
scheduleEffect(sub.notify);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
// Internal: subscribe to this signal
|
|
206
|
+
const _subscribe = (notifyFn) => {
|
|
207
|
+
const subscription = {
|
|
208
|
+
notify: notifyFn,
|
|
209
|
+
dispose: () => {
|
|
210
|
+
subscriptions.delete(subscription);
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
subscriptions.add(subscription);
|
|
214
|
+
return subscription;
|
|
215
|
+
};
|
|
216
|
+
const getter = () => {
|
|
217
|
+
if (isDisposed) {
|
|
218
|
+
return value;
|
|
219
|
+
}
|
|
220
|
+
// Track this signal as a dependency of current computed/effect
|
|
221
|
+
const context = getCurrentTrackingContext();
|
|
222
|
+
if (context) {
|
|
223
|
+
context.onDependency({ _subscribe });
|
|
224
|
+
}
|
|
225
|
+
return value;
|
|
226
|
+
};
|
|
227
|
+
const setter = (newValue) => {
|
|
228
|
+
if (isDisposed) {
|
|
229
|
+
console.warn("Attempted to set disposed signal");
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
const nextValue = typeof newValue === "function" ? newValue(value) : newValue;
|
|
233
|
+
if (!equal(nextValue, value)) {
|
|
234
|
+
value = nextValue;
|
|
235
|
+
notify();
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
const updater = (updaterFn) => {
|
|
239
|
+
setter(updaterFn(value));
|
|
240
|
+
};
|
|
241
|
+
const dispose = () => {
|
|
242
|
+
isDisposed = true;
|
|
243
|
+
subscriptions.clear();
|
|
244
|
+
};
|
|
245
|
+
const signalFn = getter;
|
|
246
|
+
signalFn.set = setter;
|
|
247
|
+
signalFn.update = updater;
|
|
248
|
+
signalFn.dispose = dispose;
|
|
249
|
+
signalFn._subscribe = _subscribe;
|
|
250
|
+
signalFn[SIGNAL_SYMBOL] = true;
|
|
251
|
+
// Add subscribe for compatibility with useSignal
|
|
252
|
+
signalFn.subscribe = (callback) => {
|
|
253
|
+
const sub = _subscribe(() => callback(value));
|
|
254
|
+
return () => sub.dispose();
|
|
255
|
+
};
|
|
256
|
+
Object.defineProperty(signalFn, "value", {
|
|
257
|
+
get: getter,
|
|
258
|
+
enumerable: true,
|
|
259
|
+
configurable: true,
|
|
260
|
+
});
|
|
261
|
+
Object.defineProperty(signalFn, "disposed", {
|
|
262
|
+
get: () => isDisposed,
|
|
263
|
+
enumerable: true,
|
|
264
|
+
configurable: true,
|
|
265
|
+
});
|
|
266
|
+
return signalFn;
|
|
267
|
+
}
|
|
268
|
+
// ============================================================================
|
|
269
|
+
// createSignal (alias for signal, used by useSignal)
|
|
270
|
+
// ============================================================================
|
|
271
|
+
/**
|
|
272
|
+
* Create a standalone signal (not tied to a component).
|
|
273
|
+
* Alias for signal() for API compatibility.
|
|
274
|
+
*/
|
|
275
|
+
export function createSignal(initialValue, options) {
|
|
276
|
+
return signal(initialValue, options);
|
|
277
|
+
}
|
|
278
|
+
// ============================================================================
|
|
279
|
+
// Computed
|
|
280
|
+
// ============================================================================
|
|
281
|
+
/**
|
|
282
|
+
* Creates a computed signal that derives its value from other signals.
|
|
283
|
+
* Computed values are memoized and only recompute when dependencies change.
|
|
284
|
+
*
|
|
285
|
+
* @example
|
|
286
|
+
* ```typescript
|
|
287
|
+
* const count = signal(0);
|
|
288
|
+
* const doubled = computed(() => count() * 2);
|
|
289
|
+
*
|
|
290
|
+
* doubled(); // 0
|
|
291
|
+
* count.set(5);
|
|
292
|
+
* doubled(); // 10 (recomputed)
|
|
293
|
+
* doubled(); // 10 (cached, no recompute)
|
|
294
|
+
* ```
|
|
295
|
+
*/
|
|
296
|
+
export function computed(computation, options) {
|
|
297
|
+
let cachedValue;
|
|
298
|
+
let isDirty = true;
|
|
299
|
+
let isDisposed = false;
|
|
300
|
+
let isComputing = false;
|
|
301
|
+
const _equal = options?.equal ?? Object.is;
|
|
302
|
+
// Subscriptions to our dependencies (signals we read)
|
|
303
|
+
const dependencySubscriptions = new Set();
|
|
304
|
+
// Subscriptions from our dependents (things that read us)
|
|
305
|
+
const dependentSubscriptions = new Set();
|
|
306
|
+
const markDirty = () => {
|
|
307
|
+
if (!isDirty && !isDisposed) {
|
|
308
|
+
isDirty = true;
|
|
309
|
+
// Notify our dependents that we might have changed
|
|
310
|
+
for (const sub of dependentSubscriptions) {
|
|
311
|
+
scheduleEffect(sub.notify);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
// Internal: subscribe to this computed
|
|
316
|
+
const _subscribe = (notifyFn) => {
|
|
317
|
+
const subscription = {
|
|
318
|
+
notify: notifyFn,
|
|
319
|
+
dispose: () => {
|
|
320
|
+
dependentSubscriptions.delete(subscription);
|
|
321
|
+
},
|
|
322
|
+
};
|
|
323
|
+
dependentSubscriptions.add(subscription);
|
|
324
|
+
return subscription;
|
|
325
|
+
};
|
|
326
|
+
const clearDependencies = () => {
|
|
327
|
+
// Unsubscribe from all current dependencies
|
|
328
|
+
for (const sub of dependencySubscriptions) {
|
|
329
|
+
sub.dispose();
|
|
330
|
+
}
|
|
331
|
+
dependencySubscriptions.clear();
|
|
332
|
+
};
|
|
333
|
+
const recompute = () => {
|
|
334
|
+
if (isComputing) {
|
|
335
|
+
throw new Error("Circular dependency detected in computed signal");
|
|
336
|
+
}
|
|
337
|
+
isComputing = true;
|
|
338
|
+
// Clear old dependencies
|
|
339
|
+
clearDependencies();
|
|
340
|
+
// Set up tracking context to capture new dependencies
|
|
341
|
+
const trackingContext = {
|
|
342
|
+
onDependency: (source) => {
|
|
343
|
+
// Subscribe to this dependency
|
|
344
|
+
const subscription = source._subscribe(markDirty);
|
|
345
|
+
dependencySubscriptions.add(subscription);
|
|
346
|
+
},
|
|
347
|
+
};
|
|
348
|
+
pushTrackingContext(trackingContext);
|
|
349
|
+
try {
|
|
350
|
+
const newValue = computation();
|
|
351
|
+
cachedValue = newValue;
|
|
352
|
+
isDirty = false;
|
|
353
|
+
return cachedValue;
|
|
354
|
+
}
|
|
355
|
+
finally {
|
|
356
|
+
popTrackingContext();
|
|
357
|
+
isComputing = false;
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
const getter = () => {
|
|
361
|
+
if (isDisposed) {
|
|
362
|
+
return cachedValue;
|
|
363
|
+
}
|
|
364
|
+
// Track this computed as dependency of parent computed/effect
|
|
365
|
+
const context = getCurrentTrackingContext();
|
|
366
|
+
if (context) {
|
|
367
|
+
context.onDependency({ _subscribe });
|
|
368
|
+
}
|
|
369
|
+
// Recompute if dirty (lazy evaluation)
|
|
370
|
+
if (isDirty) {
|
|
371
|
+
recompute();
|
|
372
|
+
}
|
|
373
|
+
return cachedValue;
|
|
374
|
+
};
|
|
375
|
+
const dispose = () => {
|
|
376
|
+
if (isDisposed)
|
|
377
|
+
return;
|
|
378
|
+
isDisposed = true;
|
|
379
|
+
isDirty = false;
|
|
380
|
+
// Unsubscribe from all dependencies - THIS FIXES THE MEMORY LEAK
|
|
381
|
+
clearDependencies();
|
|
382
|
+
// Clear our dependents (they'll get undefined on next read)
|
|
383
|
+
dependentSubscriptions.clear();
|
|
384
|
+
};
|
|
385
|
+
const computedFn = getter;
|
|
386
|
+
computedFn.dispose = dispose;
|
|
387
|
+
computedFn._subscribe = _subscribe;
|
|
388
|
+
computedFn[COMPUTED_SYMBOL] = true;
|
|
389
|
+
Object.defineProperty(computedFn, "value", {
|
|
390
|
+
get: getter,
|
|
391
|
+
enumerable: true,
|
|
392
|
+
configurable: true,
|
|
393
|
+
});
|
|
394
|
+
Object.defineProperty(computedFn, "disposed", {
|
|
395
|
+
get: () => isDisposed,
|
|
396
|
+
enumerable: true,
|
|
397
|
+
configurable: true,
|
|
398
|
+
});
|
|
399
|
+
return computedFn;
|
|
400
|
+
}
|
|
401
|
+
// ============================================================================
|
|
402
|
+
// Effect
|
|
403
|
+
// ============================================================================
|
|
404
|
+
/**
|
|
405
|
+
* Runs an effect that automatically re-runs when dependencies change.
|
|
406
|
+
* Use sparingly - prefer computed() for derived values.
|
|
407
|
+
*
|
|
408
|
+
* Best for: syncing to external APIs (localStorage, canvas, DOM, etc.)
|
|
409
|
+
*
|
|
410
|
+
* @example
|
|
411
|
+
* ```typescript
|
|
412
|
+
* const count = signal(0);
|
|
413
|
+
*
|
|
414
|
+
* const ref = effect(() => {
|
|
415
|
+
* console.log('Count:', count());
|
|
416
|
+
* });
|
|
417
|
+
*
|
|
418
|
+
* count.set(5); // logs "Count: 5"
|
|
419
|
+
*
|
|
420
|
+
* ref.dispose(); // stop the effect
|
|
421
|
+
* ```
|
|
422
|
+
*/
|
|
423
|
+
export function effect(fn) {
|
|
424
|
+
let isDisposed = false;
|
|
425
|
+
let cleanupFn;
|
|
426
|
+
const dependencySubscriptions = new Set();
|
|
427
|
+
const clearDependencies = () => {
|
|
428
|
+
for (const sub of dependencySubscriptions) {
|
|
429
|
+
sub.dispose();
|
|
430
|
+
}
|
|
431
|
+
dependencySubscriptions.clear();
|
|
432
|
+
};
|
|
433
|
+
const runEffect = () => {
|
|
434
|
+
if (isDisposed)
|
|
435
|
+
return;
|
|
436
|
+
// Run cleanup from previous execution
|
|
437
|
+
if (cleanupFn) {
|
|
438
|
+
try {
|
|
439
|
+
cleanupFn();
|
|
440
|
+
}
|
|
441
|
+
catch (error) {
|
|
442
|
+
console.error("Error in effect cleanup:", error);
|
|
443
|
+
}
|
|
444
|
+
cleanupFn = undefined;
|
|
445
|
+
}
|
|
446
|
+
// Clear old dependencies
|
|
447
|
+
clearDependencies();
|
|
448
|
+
// Set up tracking context
|
|
449
|
+
const trackingContext = {
|
|
450
|
+
onDependency: (source) => {
|
|
451
|
+
const subscription = source._subscribe(runEffect);
|
|
452
|
+
dependencySubscriptions.add(subscription);
|
|
453
|
+
},
|
|
454
|
+
};
|
|
455
|
+
pushTrackingContext(trackingContext);
|
|
456
|
+
try {
|
|
457
|
+
// Allow effect to register cleanup via callback or return value
|
|
458
|
+
const onCleanup = (cleanup) => {
|
|
459
|
+
cleanupFn = cleanup;
|
|
460
|
+
};
|
|
461
|
+
const result = fn(onCleanup);
|
|
462
|
+
// Also accept cleanup as return value (like React useEffect)
|
|
463
|
+
if (typeof result === "function") {
|
|
464
|
+
cleanupFn = result;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
finally {
|
|
468
|
+
popTrackingContext();
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
const dispose = () => {
|
|
472
|
+
if (isDisposed)
|
|
473
|
+
return;
|
|
474
|
+
isDisposed = true;
|
|
475
|
+
// Unsubscribe from all dependencies
|
|
476
|
+
clearDependencies();
|
|
477
|
+
// Run final cleanup
|
|
478
|
+
if (cleanupFn) {
|
|
479
|
+
try {
|
|
480
|
+
cleanupFn();
|
|
481
|
+
}
|
|
482
|
+
catch (error) {
|
|
483
|
+
console.error("Error in effect cleanup:", error);
|
|
484
|
+
}
|
|
485
|
+
cleanupFn = undefined;
|
|
486
|
+
}
|
|
487
|
+
};
|
|
488
|
+
// Run immediately
|
|
489
|
+
runEffect();
|
|
490
|
+
const effectRef = {
|
|
491
|
+
dispose,
|
|
492
|
+
get disposed() {
|
|
493
|
+
return isDisposed;
|
|
494
|
+
},
|
|
495
|
+
};
|
|
496
|
+
// Mark as effect for cleanup detection
|
|
497
|
+
effectRef[EFFECT_SYMBOL] = true;
|
|
498
|
+
return effectRef;
|
|
499
|
+
}
|
|
500
|
+
// ============================================================================
|
|
501
|
+
// React Hooks for Signals
|
|
502
|
+
// ============================================================================
|
|
503
|
+
/**
|
|
504
|
+
* Create a signal - reactive state that can trigger reconciliation.
|
|
505
|
+
*
|
|
506
|
+
* Unlike useState, signals:
|
|
507
|
+
* - Can be read outside of render
|
|
508
|
+
* - Can be subscribed to
|
|
509
|
+
* - Don't cause immediate re-render (schedule reconcile instead)
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
* ```tsx
|
|
513
|
+
* const MyComponent = () => {
|
|
514
|
+
* const count = useSignal(0);
|
|
515
|
+
*
|
|
516
|
+
* const handleClick = () => {
|
|
517
|
+
* count.set(c => c + 1);
|
|
518
|
+
* };
|
|
519
|
+
*
|
|
520
|
+
* return <Section>Count: {count()}</Section>;
|
|
521
|
+
* };
|
|
522
|
+
* ```
|
|
523
|
+
*/
|
|
524
|
+
export function useSignal(initialValue) {
|
|
525
|
+
// Use a version counter to trigger re-renders when signal changes
|
|
526
|
+
// The signal's internal value is the source of truth
|
|
527
|
+
const [version, setVersion] = useState(0);
|
|
528
|
+
// Get COM for requestRecompile - this triggers the scheduler when idle
|
|
529
|
+
// Returns null if not in Agentick context
|
|
530
|
+
const ctx = useContext(COMContext);
|
|
531
|
+
// Store setVersion in a ref so it's always current
|
|
532
|
+
// This fixes the issue where setVersion captured in the signal closure
|
|
533
|
+
// might be stale when called between ticks
|
|
534
|
+
const setVersionRef = useRef(setVersion);
|
|
535
|
+
setVersionRef.current = setVersion;
|
|
536
|
+
// Create signal wrapper once - stored in ref for stability
|
|
537
|
+
const signalRef = useRef(null);
|
|
538
|
+
const ctxRef = useRef(ctx);
|
|
539
|
+
ctxRef.current = ctx; // Update ctx ref on each render
|
|
540
|
+
if (signalRef.current === null) {
|
|
541
|
+
const baseSignal = createSignal(initialValue);
|
|
542
|
+
// Wrap the set function to trigger React re-render AND scheduler
|
|
543
|
+
const originalSet = baseSignal.set;
|
|
544
|
+
baseSignal.set = (newValue) => {
|
|
545
|
+
// Update the underlying signal (source of truth)
|
|
546
|
+
originalSet(newValue);
|
|
547
|
+
// Increment version to trigger re-render
|
|
548
|
+
// Use ref to always get current setter
|
|
549
|
+
setVersionRef.current((v) => v + 1);
|
|
550
|
+
// Request recompile through COM → scheduler → reconcile
|
|
551
|
+
// This triggers the reactive model when session is idle
|
|
552
|
+
if (ctxRef.current?.requestRecompile) {
|
|
553
|
+
ctxRef.current.requestRecompile("useSignal state change");
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
signalRef.current = baseSignal;
|
|
557
|
+
}
|
|
558
|
+
// Force unused variable to avoid lint warning
|
|
559
|
+
void version;
|
|
560
|
+
// Debug value for React DevTools
|
|
561
|
+
useDebugValue(signalRef.current.value, (v) => typeof v === "object" ? `Object(${Object.keys(v).length} keys)` : String(v));
|
|
562
|
+
return signalRef.current;
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Create a computed signal that derives from other signals.
|
|
566
|
+
*
|
|
567
|
+
* @example
|
|
568
|
+
* ```tsx
|
|
569
|
+
* const count = useSignal(5);
|
|
570
|
+
* const doubled = useComputed(() => count() * 2, [count]);
|
|
571
|
+
* // doubled() === 10
|
|
572
|
+
* ```
|
|
573
|
+
*/
|
|
574
|
+
export function useComputed(compute, deps) {
|
|
575
|
+
// Use version counter to trigger re-renders
|
|
576
|
+
const [, setVersion] = useState(0);
|
|
577
|
+
// Create signal wrapper once
|
|
578
|
+
const computedRef = useRef(null);
|
|
579
|
+
if (computedRef.current === null) {
|
|
580
|
+
const baseSignal = createSignal(compute());
|
|
581
|
+
// Wrap set to trigger React re-render
|
|
582
|
+
const originalSet = baseSignal.set;
|
|
583
|
+
baseSignal.set = (newValue) => {
|
|
584
|
+
originalSet(newValue);
|
|
585
|
+
setVersion((v) => v + 1);
|
|
586
|
+
};
|
|
587
|
+
computedRef.current = baseSignal;
|
|
588
|
+
}
|
|
589
|
+
// Recompute when deps change
|
|
590
|
+
useEffect(() => {
|
|
591
|
+
const unsubscribes = deps.map((dep) => dep.subscribe(() => {
|
|
592
|
+
const newValue = compute();
|
|
593
|
+
computedRef.current.set(newValue);
|
|
594
|
+
}));
|
|
595
|
+
return () => {
|
|
596
|
+
unsubscribes.forEach((unsub) => unsub());
|
|
597
|
+
};
|
|
598
|
+
}, deps);
|
|
599
|
+
// Debug value for React DevTools
|
|
600
|
+
useDebugValue(computedRef.current.value, (v) => typeof v === "object"
|
|
601
|
+
? `Computed(${Object.keys(v).length} keys)`
|
|
602
|
+
: `Computed(${String(v)})`);
|
|
603
|
+
return computedRef.current;
|
|
604
|
+
}
|
|
605
|
+
// ============================================================================
|
|
606
|
+
// Utilities
|
|
607
|
+
// ============================================================================
|
|
608
|
+
/**
|
|
609
|
+
* Read a signal without tracking it as a dependency.
|
|
610
|
+
* Useful when you want to read a value in a computed/effect without
|
|
611
|
+
* triggering re-runs when that value changes.
|
|
612
|
+
*
|
|
613
|
+
* @example
|
|
614
|
+
* ```typescript
|
|
615
|
+
* effect(() => {
|
|
616
|
+
* const user = currentUser();
|
|
617
|
+
* const count = untracked(() => counter()); // won't trigger re-run
|
|
618
|
+
* console.log(`User ${user} has count ${count}`);
|
|
619
|
+
* });
|
|
620
|
+
* ```
|
|
621
|
+
*/
|
|
622
|
+
export function untracked(fn) {
|
|
623
|
+
const ctx = getSignalContext();
|
|
624
|
+
// Temporarily remove tracking context
|
|
625
|
+
const savedStack = [...ctx.trackingStack];
|
|
626
|
+
ctx.trackingStack.length = 0;
|
|
627
|
+
try {
|
|
628
|
+
return fn();
|
|
629
|
+
}
|
|
630
|
+
finally {
|
|
631
|
+
ctx.trackingStack.push(...savedStack);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Check if a value is a signal.
|
|
636
|
+
*/
|
|
637
|
+
export function isSignal(value) {
|
|
638
|
+
return typeof value === "function" && value[SIGNAL_SYMBOL] === true;
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Check if a value is a computed signal.
|
|
642
|
+
*/
|
|
643
|
+
export function isComputed(value) {
|
|
644
|
+
return typeof value === "function" && value[COMPUTED_SYMBOL] === true;
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Check if a value is an effect ref.
|
|
648
|
+
*/
|
|
649
|
+
export function isEffect(value) {
|
|
650
|
+
return value !== null && typeof value === "object" && value[EFFECT_SYMBOL] === true;
|
|
651
|
+
}
|
|
652
|
+
// ============================================================================
|
|
653
|
+
// COM State Signal
|
|
654
|
+
// ============================================================================
|
|
655
|
+
export const COM_SIGNAL_SYMBOL = Symbol.for("agentick.comSignal");
|
|
656
|
+
/**
|
|
657
|
+
* Creates a signal bound to COM state.
|
|
658
|
+
* Changes sync bidirectionally between signal and COM.
|
|
659
|
+
*
|
|
660
|
+
* @internal Used by comState() after COM is available
|
|
661
|
+
*/
|
|
662
|
+
export function createCOMStateSignal(ctx, key, initialValue) {
|
|
663
|
+
const sig = signal(ctx.getState(key) ?? initialValue);
|
|
664
|
+
// Flag to prevent circular updates
|
|
665
|
+
let isUpdatingFromCOM = false;
|
|
666
|
+
// Listen for COM state changes from other sources
|
|
667
|
+
const handler = (changedKey, value) => {
|
|
668
|
+
if (changedKey === key && !isUpdatingFromCOM) {
|
|
669
|
+
isUpdatingFromCOM = true;
|
|
670
|
+
try {
|
|
671
|
+
// Update signal without triggering our own setter logic
|
|
672
|
+
const internalSet = sig.set;
|
|
673
|
+
internalSet(value);
|
|
674
|
+
// AUTOMATIC RECOMPILATION: If COM state changes during render phase,
|
|
675
|
+
// request recompile to ensure consistency across sibling components
|
|
676
|
+
// BUT: Skip in phases where recompile is unnecessary
|
|
677
|
+
if (isCompilerRendering() && !shouldSkipRecompile()) {
|
|
678
|
+
const compiler = getActiveCompiler();
|
|
679
|
+
if (compiler) {
|
|
680
|
+
const ctxObj = ctx;
|
|
681
|
+
if (ctxObj.requestRecompile) {
|
|
682
|
+
ctxObj.requestRecompile(`comState '${key}' changed during render`);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
finally {
|
|
688
|
+
isUpdatingFromCOM = false;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
};
|
|
692
|
+
ctx.on("state:changed", handler);
|
|
693
|
+
// Override set to also update COM
|
|
694
|
+
const originalSet = sig.set;
|
|
695
|
+
sig.set = (value) => {
|
|
696
|
+
if (isUpdatingFromCOM) {
|
|
697
|
+
originalSet.call(sig, value);
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
const currentValue = sig();
|
|
701
|
+
const nextValue = typeof value === "function"
|
|
702
|
+
? value(currentValue)
|
|
703
|
+
: value;
|
|
704
|
+
// Bailout if value hasn't changed
|
|
705
|
+
if (Object.is(currentValue, nextValue)) {
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
// DEV WARNING: Setting comState during render
|
|
709
|
+
if (process.env["NODE_ENV"] === "development" && isCompilerRendering()) {
|
|
710
|
+
console.warn(`[Agentick] comState '${key}' is being set during render phase.\n` +
|
|
711
|
+
`This may cause sibling components to see stale data in the current iteration.\n` +
|
|
712
|
+
`Consider updating state in lifecycle methods (onTickStart, onMount) instead.\n` +
|
|
713
|
+
`An automatic recompile will be triggered to ensure consistency.`);
|
|
714
|
+
}
|
|
715
|
+
// Update COM first (will trigger handler, but flag prevents circular)
|
|
716
|
+
isUpdatingFromCOM = true;
|
|
717
|
+
try {
|
|
718
|
+
ctx.setState(key, nextValue);
|
|
719
|
+
}
|
|
720
|
+
finally {
|
|
721
|
+
isUpdatingFromCOM = false;
|
|
722
|
+
}
|
|
723
|
+
// Then update signal
|
|
724
|
+
originalSet.call(sig, nextValue);
|
|
725
|
+
// AUTOMATIC RECOMPILATION: Request recompile after state change
|
|
726
|
+
// This ensures useComState behaves like useState for triggering re-renders
|
|
727
|
+
// BUT: Skip recompile in certain phases where it's unnecessary:
|
|
728
|
+
// - tickStart: Render is about to happen anyway
|
|
729
|
+
// - tickEnd: Current tick is done, next tick will see the update
|
|
730
|
+
// - complete: Execution is complete, no more renders
|
|
731
|
+
// - unmount: Component is being removed
|
|
732
|
+
// - render (class onMount): Class component onMount runs during render, before render() is called
|
|
733
|
+
//
|
|
734
|
+
// ALLOW recompile in:
|
|
735
|
+
// - mount (useOnMount): Function component useOnMount runs after first render, can trigger recompile
|
|
736
|
+
if (!shouldSkipRecompile()) {
|
|
737
|
+
const ctxObj = ctx;
|
|
738
|
+
if (ctxObj.requestRecompile) {
|
|
739
|
+
ctxObj.requestRecompile(`comState '${key}' updated`);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
};
|
|
743
|
+
// Override dispose to cleanup COM listener
|
|
744
|
+
const originalDispose = sig.dispose;
|
|
745
|
+
sig.dispose = () => {
|
|
746
|
+
if (ctx.off) {
|
|
747
|
+
ctx.off("state:changed", handler);
|
|
748
|
+
}
|
|
749
|
+
originalDispose.call(sig);
|
|
750
|
+
};
|
|
751
|
+
// Mark as COM signal
|
|
752
|
+
sig[COM_SIGNAL_SYMBOL] = key;
|
|
753
|
+
return sig;
|
|
754
|
+
}
|
|
755
|
+
export const WATCH_SIGNAL_SYMBOL = Symbol.for("agentick.watchSignal");
|
|
756
|
+
export const PROPS_SIGNAL_SYMBOL = Symbol.for("agentick.propsSignal");
|
|
757
|
+
export const REQUIRED_INPUT_SYMBOL = Symbol.for("agentick.requiredInput");
|
|
758
|
+
/**
|
|
759
|
+
* Creates a read-only signal that watches COM state.
|
|
760
|
+
* The signal updates when COM state changes, but cannot modify it.
|
|
761
|
+
*
|
|
762
|
+
* @internal Used by watchComState() and watch()
|
|
763
|
+
*/
|
|
764
|
+
export function createReadonlyCOMStateSignal(ctx, key, defaultValue) {
|
|
765
|
+
let value = ctx.getState(key) ?? defaultValue;
|
|
766
|
+
let isDisposed = false;
|
|
767
|
+
// Listen for COM state changes
|
|
768
|
+
const handler = (changedKey, newValue) => {
|
|
769
|
+
if (changedKey === key && !isDisposed) {
|
|
770
|
+
value = newValue;
|
|
771
|
+
// Notify any computed/effects that depend on this
|
|
772
|
+
scheduleEffect(() => { }); // Force reactivity check
|
|
773
|
+
// AUTOMATIC RECOMPILATION: If watched COM state changes during render,
|
|
774
|
+
// request recompile to ensure consistency across sibling components
|
|
775
|
+
// BUT: Skip in phases where recompile is unnecessary
|
|
776
|
+
if (isCompilerRendering() && !shouldSkipRecompile()) {
|
|
777
|
+
const compiler = getActiveCompiler();
|
|
778
|
+
if (compiler) {
|
|
779
|
+
const ctxObj = ctx;
|
|
780
|
+
if (ctxObj.requestRecompile) {
|
|
781
|
+
ctxObj.requestRecompile(`watched comState '${key}' changed during render`);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
};
|
|
787
|
+
ctx.on("state:changed", handler);
|
|
788
|
+
const getter = () => {
|
|
789
|
+
if (isDisposed)
|
|
790
|
+
return value;
|
|
791
|
+
// Track as dependency if inside computed/effect
|
|
792
|
+
const context = getCurrentTrackingContext();
|
|
793
|
+
if (context) {
|
|
794
|
+
// Create a virtual subscription for tracking
|
|
795
|
+
context.onDependency({
|
|
796
|
+
_subscribe: (notify) => ({
|
|
797
|
+
notify,
|
|
798
|
+
dispose: () => { },
|
|
799
|
+
}),
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
return value;
|
|
803
|
+
};
|
|
804
|
+
const dispose = () => {
|
|
805
|
+
if (isDisposed)
|
|
806
|
+
return;
|
|
807
|
+
isDisposed = true;
|
|
808
|
+
if (ctx.off) {
|
|
809
|
+
ctx.off("state:changed", handler);
|
|
810
|
+
}
|
|
811
|
+
};
|
|
812
|
+
const readonlySignal = Object.assign(getter, {
|
|
813
|
+
dispose,
|
|
814
|
+
get value() {
|
|
815
|
+
return getter();
|
|
816
|
+
},
|
|
817
|
+
get disposed() {
|
|
818
|
+
return isDisposed;
|
|
819
|
+
},
|
|
820
|
+
});
|
|
821
|
+
// Mark for cleanup detection
|
|
822
|
+
readonlySignal[WATCH_SIGNAL_SYMBOL] = key;
|
|
823
|
+
return readonlySignal;
|
|
824
|
+
}
|
|
825
|
+
//# sourceMappingURL=signal.js.map
|