@treenity/core 1.0.47 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chain.d.ts +20 -0
- package/dist/chain.d.ts.map +1 -0
- package/dist/chain.js +59 -0
- package/dist/chain.js.map +1 -0
- package/dist/client/handle.d.ts +13 -0
- package/dist/client/handle.d.ts.map +1 -0
- package/dist/client/handle.js +46 -0
- package/dist/client/handle.js.map +1 -0
- package/dist/client/index.d.ts +21 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +5 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/trpc.d.ts +13 -0
- package/dist/client/trpc.d.ts.map +1 -0
- package/dist/client/trpc.js +78 -0
- package/dist/client/trpc.js.map +1 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +2 -0
- package/dist/client.js.map +1 -0
- package/dist/comp/handle.d.ts +14 -0
- package/dist/comp/handle.d.ts.map +1 -0
- package/dist/comp/handle.js +21 -0
- package/dist/comp/handle.js.map +1 -0
- package/dist/comp/index.d.ts +42 -0
- package/dist/comp/index.d.ts.map +1 -0
- package/dist/comp/index.js +126 -0
- package/dist/comp/index.js.map +1 -0
- package/dist/comp/needs.d.ts +26 -0
- package/dist/comp/needs.d.ts.map +1 -0
- package/dist/comp/needs.js +101 -0
- package/dist/comp/needs.js.map +1 -0
- package/dist/comp/validate.d.ts +13 -0
- package/dist/comp/validate.d.ts.map +1 -0
- package/dist/comp/validate.js +117 -0
- package/dist/comp/validate.js.map +1 -0
- package/dist/comp.d.ts +2 -0
- package/dist/comp.d.ts.map +1 -0
- package/dist/comp.js +2 -0
- package/dist/comp.js.map +1 -0
- package/dist/contexts/schema/index.d.ts +7 -0
- package/dist/contexts/schema/index.d.ts.map +1 -0
- package/dist/contexts/schema/index.js +2 -0
- package/dist/contexts/schema/index.js.map +1 -0
- package/dist/contexts/schema.d.ts +2 -0
- package/dist/contexts/schema.d.ts.map +1 -0
- package/dist/contexts/schema.js +2 -0
- package/dist/contexts/schema.js.map +1 -0
- package/dist/contexts/service/index.d.ts +31 -0
- package/dist/contexts/service/index.d.ts.map +1 -0
- package/dist/contexts/service/index.js +16 -0
- package/dist/contexts/service/index.js.map +1 -0
- package/dist/contexts/service.d.ts +1 -14
- package/dist/contexts/service.d.ts.map +1 -1
- package/dist/contexts/service.js +2 -0
- package/dist/contexts/service.js.map +1 -0
- package/dist/contexts/telegram/index.d.ts +19 -0
- package/dist/contexts/telegram/index.d.ts.map +1 -0
- package/dist/contexts/telegram/index.js +89 -0
- package/dist/contexts/telegram/index.js.map +1 -0
- package/dist/contexts/text/index.d.ts +7 -0
- package/dist/contexts/text/index.d.ts.map +1 -0
- package/dist/contexts/text/index.js +9 -0
- package/dist/contexts/text/index.js.map +1 -0
- package/dist/contexts/text.d.ts +2 -0
- package/dist/contexts/text.d.ts.map +1 -0
- package/dist/contexts/text.js +2 -0
- package/dist/contexts/text.js.map +1 -0
- package/dist/core/component.d.ts +41 -0
- package/dist/core/component.d.ts.map +1 -0
- package/dist/core/component.js +105 -0
- package/dist/core/component.js.map +1 -0
- package/dist/core/context.d.ts +5 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +3 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +8 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/path.d.ts +7 -0
- package/dist/core/path.d.ts.map +1 -0
- package/dist/core/path.js +37 -0
- package/dist/core/path.js.map +1 -0
- package/dist/core/registry.d.ts +16 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +100 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core.d.ts +2 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +2 -0
- package/dist/core.js.map +1 -0
- package/dist/log.d.ts +8 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +31 -0
- package/dist/log.js.map +1 -0
- package/dist/mod/discover.d.ts +4 -0
- package/dist/mod/discover.d.ts.map +1 -0
- package/dist/mod/discover.js +103 -0
- package/dist/mod/discover.js.map +1 -0
- package/dist/mod/examples/ticker/seed.d.ts +3 -0
- package/dist/mod/examples/ticker/seed.d.ts.map +1 -0
- package/dist/mod/examples/ticker/seed.js +16 -0
- package/dist/mod/examples/ticker/seed.js.map +1 -0
- package/dist/mod/examples/ticker/service.d.ts +2 -0
- package/dist/mod/examples/ticker/service.d.ts.map +1 -0
- package/dist/mod/examples/ticker/service.js +18 -0
- package/dist/mod/examples/ticker/service.js.map +1 -0
- package/dist/mod/examples/ticker/types.d.ts +16 -0
- package/dist/mod/examples/ticker/types.d.ts.map +1 -0
- package/dist/mod/examples/ticker/types.js +20 -0
- package/dist/mod/examples/ticker/types.js.map +1 -0
- package/dist/mod/examples/ticker/view.d.ts +2 -0
- package/dist/mod/examples/ticker/view.d.ts.map +1 -0
- package/dist/mod/examples/ticker/view.js +10 -0
- package/dist/mod/examples/ticker/view.js.map +1 -0
- package/dist/mod/index.d.ts +11 -0
- package/dist/mod/index.d.ts.map +1 -0
- package/dist/mod/index.js +8 -0
- package/dist/mod/index.js.map +1 -0
- package/dist/mod/loader.d.ts +18 -0
- package/dist/mod/loader.d.ts.map +1 -0
- package/dist/mod/loader.js +154 -0
- package/dist/mod/loader.js.map +1 -0
- package/dist/mod/optimistic.d.ts +34 -0
- package/dist/mod/optimistic.d.ts.map +1 -0
- package/dist/mod/optimistic.js +176 -0
- package/dist/mod/optimistic.js.map +1 -0
- package/dist/mod/prefab.d.ts +18 -0
- package/dist/mod/prefab.d.ts.map +1 -0
- package/dist/mod/prefab.js +42 -0
- package/dist/mod/prefab.js.map +1 -0
- package/dist/mod/tracking.d.ts +8 -0
- package/dist/mod/tracking.d.ts.map +1 -0
- package/dist/mod/tracking.js +44 -0
- package/dist/mod/tracking.js.map +1 -0
- package/dist/mod/types.d.ts +31 -0
- package/dist/mod/types.d.ts.map +1 -0
- package/dist/mod/types.js +5 -0
- package/dist/mod/types.js.map +1 -0
- package/dist/mod.d.ts +2 -0
- package/dist/mod.d.ts.map +1 -0
- package/dist/mod.js +2 -0
- package/dist/mod.js.map +1 -0
- package/dist/mods/autostart/server.d.ts +2 -0
- package/dist/mods/autostart/server.d.ts.map +1 -0
- package/dist/mods/autostart/server.js +2 -0
- package/dist/mods/autostart/server.js.map +1 -0
- package/dist/mods/autostart/service.d.ts +14 -0
- package/dist/mods/autostart/service.d.ts.map +1 -0
- package/dist/mods/autostart/service.js +88 -0
- package/dist/mods/autostart/service.js.map +1 -0
- package/dist/mods/llm/index.d.ts +13 -0
- package/dist/mods/llm/index.d.ts.map +1 -0
- package/dist/mods/llm/index.js +43 -0
- package/dist/mods/llm/index.js.map +1 -0
- package/dist/mods/llm/server.d.ts +2 -0
- package/dist/mods/llm/server.d.ts.map +1 -0
- package/dist/mods/llm/server.js +2 -0
- package/dist/mods/llm/server.js.map +1 -0
- package/dist/mods/mcp/server.d.ts +3 -0
- package/dist/mods/mcp/server.d.ts.map +1 -0
- package/dist/mods/mcp/server.js +3 -0
- package/dist/mods/mcp/server.js.map +1 -0
- package/dist/mods/mcp/service.d.ts +2 -0
- package/dist/mods/mcp/service.d.ts.map +1 -0
- package/dist/mods/mcp/service.js +17 -0
- package/dist/mods/mcp/service.js.map +1 -0
- package/dist/mods/mcp/types.d.ts +5 -0
- package/dist/mods/mcp/types.d.ts.map +1 -0
- package/dist/mods/mcp/types.js +7 -0
- package/dist/mods/mcp/types.js.map +1 -0
- package/dist/mods/treenity/agent-port.d.ts +2 -0
- package/dist/mods/treenity/agent-port.d.ts.map +1 -0
- package/dist/mods/treenity/agent-port.js +76 -0
- package/dist/mods/treenity/agent-port.js.map +1 -0
- package/dist/mods/treenity/groups.d.ts +2 -0
- package/dist/mods/treenity/groups.d.ts.map +1 -0
- package/dist/mods/treenity/groups.js +18 -0
- package/dist/mods/treenity/groups.js.map +1 -0
- package/dist/mods/treenity/mod-type.d.ts +2 -0
- package/dist/mods/treenity/mod-type.d.ts.map +1 -0
- package/dist/mods/treenity/mod-type.js +9 -0
- package/dist/mods/treenity/mod-type.js.map +1 -0
- package/dist/mods/treenity/seed.d.ts +2 -0
- package/dist/mods/treenity/seed.d.ts.map +1 -0
- package/dist/mods/treenity/seed.js +53 -0
- package/dist/mods/treenity/seed.js.map +1 -0
- package/dist/mods/treenity/server.d.ts +5 -0
- package/dist/mods/treenity/server.d.ts.map +1 -0
- package/dist/mods/treenity/server.js +5 -0
- package/dist/mods/treenity/server.js.map +1 -0
- package/dist/mods/treenity/system.d.ts +36 -0
- package/dist/mods/treenity/system.d.ts.map +1 -0
- package/dist/mods/treenity/system.js +61 -0
- package/dist/mods/treenity/system.js.map +1 -0
- package/dist/mods/uix/client.d.ts +3 -0
- package/dist/mods/uix/client.d.ts.map +1 -0
- package/dist/mods/uix/client.js +96 -0
- package/dist/mods/uix/client.js.map +1 -0
- package/dist/mods/uix/compile.d.ts +7 -0
- package/dist/mods/uix/compile.d.ts.map +1 -0
- package/dist/mods/uix/compile.js +94 -0
- package/dist/mods/uix/compile.js.map +1 -0
- package/dist/mods/uix/jsx-parser.d.ts +2 -0
- package/dist/mods/uix/jsx-parser.d.ts.map +1 -0
- package/dist/mods/uix/jsx-parser.js +565 -0
- package/dist/mods/uix/jsx-parser.js.map +1 -0
- package/dist/mods/uix/verify.d.ts +7 -0
- package/dist/mods/uix/verify.d.ts.map +1 -0
- package/dist/mods/uix/verify.js +59 -0
- package/dist/mods/uix/verify.js.map +1 -0
- package/dist/schema/catalog.d.ts +23 -0
- package/dist/schema/catalog.d.ts.map +1 -0
- package/dist/schema/catalog.js +82 -0
- package/dist/schema/catalog.js.map +1 -0
- package/dist/schema/extract-schemas.d.ts +5 -0
- package/dist/schema/extract-schemas.d.ts.map +1 -0
- package/dist/schema/extract-schemas.js +444 -0
- package/dist/schema/extract-schemas.js.map +1 -0
- package/dist/schema/load.d.ts +2 -0
- package/dist/schema/load.d.ts.map +1 -0
- package/dist/schema/load.js +23 -0
- package/dist/schema/load.js.map +1 -0
- package/dist/schema/test-fixture.types.d.ts +2 -0
- package/dist/schema/test-fixture.types.d.ts.map +1 -0
- package/dist/schema/test-fixture.types.js +19 -0
- package/dist/schema/test-fixture.types.js.map +1 -0
- package/dist/schema/test-opaque.d.ts +3 -0
- package/dist/schema/test-opaque.d.ts.map +1 -0
- package/dist/schema/test-opaque.js +43 -0
- package/dist/schema/test-opaque.js.map +1 -0
- package/dist/schema/types.d.ts +37 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/schema/types.js +3 -0
- package/dist/schema/types.js.map +1 -0
- package/dist/server/actions.d.ts +35 -0
- package/dist/server/actions.d.ts.map +1 -0
- package/dist/server/actions.js +170 -0
- package/dist/server/actions.js.map +1 -0
- package/dist/server/agent.d.ts +6 -0
- package/dist/server/agent.d.ts.map +1 -0
- package/dist/server/agent.js +15 -0
- package/dist/server/agent.js.map +1 -0
- package/dist/server/auth.d.ts +39 -0
- package/dist/server/auth.d.ts.map +1 -0
- package/dist/server/auth.js +335 -0
- package/dist/server/auth.js.map +1 -0
- package/dist/server/client.d.ts +183 -0
- package/dist/server/client.d.ts.map +1 -0
- package/dist/server/client.js +22 -0
- package/dist/server/client.js.map +1 -0
- package/dist/server/cookies.d.ts +5 -0
- package/dist/server/cookies.d.ts.map +1 -0
- package/dist/server/cookies.js +24 -0
- package/dist/server/cookies.js.map +1 -0
- package/dist/server/doc-index.d.ts +38 -0
- package/dist/server/doc-index.d.ts.map +1 -0
- package/dist/server/doc-index.js +244 -0
- package/dist/server/doc-index.js.map +1 -0
- package/dist/server/errors.d.ts +7 -0
- package/dist/server/errors.d.ts.map +1 -0
- package/dist/server/errors.js +11 -0
- package/dist/server/errors.js.map +1 -0
- package/dist/server/factory.d.ts +23 -0
- package/dist/server/factory.d.ts.map +1 -0
- package/dist/server/factory.js +70 -0
- package/dist/server/factory.js.map +1 -0
- package/dist/server/main.d.ts +6 -0
- package/dist/server/main.d.ts.map +1 -0
- package/dist/server/main.js +45 -0
- package/dist/server/main.js.map +1 -0
- package/dist/server/mcp.d.ts +5 -0
- package/dist/server/mcp.d.ts.map +1 -0
- package/dist/server/mcp.js +280 -0
- package/dist/server/mcp.js.map +1 -0
- package/dist/server/migrate.d.ts +3 -0
- package/dist/server/migrate.d.ts.map +1 -0
- package/dist/server/migrate.js +56 -0
- package/dist/server/migrate.js.map +1 -0
- package/dist/server/mod-catalog.d.ts +14 -0
- package/dist/server/mod-catalog.d.ts.map +1 -0
- package/dist/server/mod-catalog.js +40 -0
- package/dist/server/mod-catalog.js.map +1 -0
- package/dist/server/mods-mount.d.ts +4 -0
- package/dist/server/mods-mount.d.ts.map +1 -0
- package/dist/server/mods-mount.js +169 -0
- package/dist/server/mods-mount.js.map +1 -0
- package/dist/server/mount-adapters.d.ts +9 -0
- package/dist/server/mount-adapters.d.ts.map +1 -0
- package/dist/server/mount-adapters.js +75 -0
- package/dist/server/mount-adapters.js.map +1 -0
- package/dist/server/mount.d.ts +3 -0
- package/dist/server/mount.d.ts.map +1 -0
- package/dist/server/mount.js +195 -0
- package/dist/server/mount.js.map +1 -0
- package/dist/server/prefab.d.ts +18 -0
- package/dist/server/prefab.d.ts.map +1 -0
- package/dist/server/prefab.js +70 -0
- package/dist/server/prefab.js.map +1 -0
- package/dist/server/seed/index.d.ts +6 -0
- package/dist/server/seed/index.d.ts.map +1 -0
- package/dist/server/seed/index.js +16 -0
- package/dist/server/seed/index.js.map +1 -0
- package/dist/server/server.d.ts +28 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +117 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/sub.d.ts +34 -0
- package/dist/server/sub.d.ts.map +1 -0
- package/dist/server/sub.js +174 -0
- package/dist/server/sub.js.map +1 -0
- package/dist/server/trpc.d.ts +192 -0
- package/dist/server/trpc.d.ts.map +1 -0
- package/dist/server/trpc.js +319 -0
- package/dist/server/trpc.js.map +1 -0
- package/dist/server/types-mount.d.ts +3 -0
- package/dist/server/types-mount.d.ts.map +1 -0
- package/dist/server/types-mount.js +144 -0
- package/dist/server/types-mount.js.map +1 -0
- package/dist/server/validate.d.ts +3 -0
- package/dist/server/validate.d.ts.map +1 -0
- package/dist/server/validate.js +20 -0
- package/dist/server/validate.js.map +1 -0
- package/dist/server/volatile.d.ts +11 -0
- package/dist/server/volatile.d.ts.map +1 -0
- package/dist/server/volatile.js +26 -0
- package/dist/server/volatile.js.map +1 -0
- package/dist/server/watch.d.ts +23 -0
- package/dist/server/watch.d.ts.map +1 -0
- package/dist/server/watch.js +178 -0
- package/dist/server/watch.js.map +1 -0
- package/dist/tree/cache.d.ts +3 -0
- package/dist/tree/cache.d.ts.map +1 -0
- package/dist/tree/cache.js +48 -0
- package/dist/tree/cache.js.map +1 -0
- package/dist/tree/fs.d.ts +3 -0
- package/dist/tree/fs.d.ts.map +1 -0
- package/dist/tree/fs.js +274 -0
- package/dist/tree/fs.js.map +1 -0
- package/dist/tree/index.d.ts +38 -0
- package/dist/tree/index.d.ts.map +1 -0
- package/dist/tree/index.js +182 -0
- package/dist/tree/index.js.map +1 -0
- package/dist/tree/inflight.d.ts +2 -0
- package/dist/tree/inflight.d.ts.map +1 -0
- package/dist/tree/inflight.js +15 -0
- package/dist/tree/inflight.js.map +1 -0
- package/dist/tree/json-codec.d.ts +2 -0
- package/dist/tree/json-codec.d.ts.map +1 -0
- package/dist/tree/json-codec.js +13 -0
- package/dist/tree/json-codec.js.map +1 -0
- package/dist/tree/mimefs.d.ts +13 -0
- package/dist/tree/mimefs.d.ts.map +1 -0
- package/dist/tree/mimefs.js +124 -0
- package/dist/tree/mimefs.js.map +1 -0
- package/dist/tree/mongo.d.ts +5 -0
- package/dist/tree/mongo.d.ts.map +1 -0
- package/dist/tree/mongo.js +110 -0
- package/dist/tree/mongo.js.map +1 -0
- package/dist/tree/patch.d.ts +30 -0
- package/dist/tree/patch.d.ts.map +1 -0
- package/dist/tree/patch.js +112 -0
- package/dist/tree/patch.js.map +1 -0
- package/dist/tree/query.d.ts +12 -0
- package/dist/tree/query.d.ts.map +1 -0
- package/dist/tree/query.js +61 -0
- package/dist/tree/query.js.map +1 -0
- package/dist/tree/repath.d.ts +3 -0
- package/dist/tree/repath.d.ts.map +1 -0
- package/dist/tree/repath.js +38 -0
- package/dist/tree/repath.js.map +1 -0
- package/dist/tree-chain.d.ts +18 -0
- package/dist/tree-chain.d.ts.map +1 -0
- package/dist/tree-chain.js +109 -0
- package/dist/tree-chain.js.map +1 -0
- package/dist/tree.d.ts +2 -0
- package/dist/tree.d.ts.map +1 -0
- package/dist/tree.js +2 -0
- package/dist/tree.js.map +1 -0
- package/dist/uri.d.ts +11 -0
- package/dist/uri.d.ts.map +1 -0
- package/dist/uri.js +79 -0
- package/dist/uri.js.map +1 -0
- package/package.json +39 -40
- package/src/chain.test.ts +190 -0
- package/src/chain.ts +82 -0
- package/src/client/client.test.ts +192 -0
- package/src/client/handle.ts +53 -0
- package/src/client/index.ts +18 -0
- package/src/client/trpc.ts +91 -0
- package/src/client.ts +1 -0
- package/src/comp/CLAUDE.md +14 -0
- package/src/comp/handle.ts +36 -0
- package/src/comp/index.test.ts +129 -0
- package/src/comp/index.ts +175 -0
- package/src/comp/needs.test.ts +499 -0
- package/src/comp/needs.ts +113 -0
- package/src/comp/validate.test.ts +304 -0
- package/src/comp/validate.ts +125 -0
- package/src/comp.ts +1 -0
- package/src/contexts/schema/index.ts +7 -0
- package/src/contexts/schema.ts +1 -0
- package/src/contexts/service/index.test.ts +323 -0
- package/src/contexts/service/index.ts +43 -0
- package/src/contexts/service.ts +1 -0
- package/src/contexts/telegram/index.ts +115 -0
- package/src/contexts/text/index.test.ts +31 -0
- package/src/contexts/text/index.ts +18 -0
- package/src/contexts/text.ts +1 -0
- package/src/core/component.ts +151 -0
- package/src/core/context.ts +14 -0
- package/src/core/index.test.ts +203 -0
- package/src/core/index.ts +9 -0
- package/src/core/path.ts +35 -0
- package/src/core/registry.ts +115 -0
- package/src/core.ts +1 -0
- package/src/log.test.ts +70 -0
- package/src/log.ts +28 -0
- package/src/mod/discover.test.ts +133 -0
- package/src/mod/discover.ts +100 -0
- package/src/mod/docs/00-index.md +19 -0
- package/src/mod/docs/01-primitives.md +38 -0
- package/src/mod/docs/02-core-api.md +68 -0
- package/src/mod/docs/03-registry.md +30 -0
- package/src/mod/docs/04-store.md +62 -0
- package/src/mod/docs/05-comp.md +111 -0
- package/src/mod/docs/06-actions.md +193 -0
- package/src/mod/docs/07-realtime.md +100 -0
- package/src/mod/docs/08-services.md +33 -0
- package/src/mod/docs/09-mounts.md +43 -0
- package/src/mod/docs/10-acl.md +60 -0
- package/src/mod/docs/11-server.md +62 -0
- package/src/mod/docs/12-conventions.md +65 -0
- package/src/mod/docs/13-example.md +132 -0
- package/src/mod/docs/14-mod-format.md +304 -0
- package/src/mod/docs/15-documenting-types.md +156 -0
- package/src/mod/examples/ticker/seed.ts +19 -0
- package/src/mod/examples/ticker/service.ts +20 -0
- package/src/mod/examples/ticker/ticker.test.ts +18 -0
- package/src/mod/examples/ticker/types.ts +22 -0
- package/src/mod/examples/ticker/view.tsx +19 -0
- package/src/mod/index.ts +12 -0
- package/src/mod/loader.test.ts +168 -0
- package/src/mod/loader.ts +174 -0
- package/src/mod/optimistic.test.ts +446 -0
- package/src/mod/optimistic.ts +210 -0
- package/src/mod/prefab.ts +62 -0
- package/src/mod/tracking.test.ts +59 -0
- package/src/mod/tracking.ts +51 -0
- package/src/mod/types.ts +40 -0
- package/src/mod.ts +1 -0
- package/src/mods/autostart/CLAUDE.md +6 -0
- package/src/mods/autostart/autostart.test.ts +85 -0
- package/src/mods/autostart/server.ts +1 -0
- package/src/mods/autostart/service.ts +98 -0
- package/src/mods/llm/CLAUDE.md +6 -0
- package/src/mods/llm/index.ts +57 -0
- package/src/mods/llm/llm.test.ts +109 -0
- package/src/mods/llm/server.ts +1 -0
- package/src/mods/mcp/CLAUDE.md +6 -0
- package/src/mods/mcp/server.ts +2 -0
- package/src/mods/mcp/service.ts +19 -0
- package/src/mods/mcp/types.ts +7 -0
- package/src/mods/treenity/agent-port.ts +93 -0
- package/src/mods/treenity/groups.ts +19 -0
- package/src/mods/treenity/mod-type.ts +10 -0
- package/src/mods/treenity/seed.ts +56 -0
- package/src/mods/treenity/server.ts +4 -0
- package/src/mods/treenity/system.ts +70 -0
- package/src/mods/uix/CLAUDE.md +7 -0
- package/src/mods/uix/client.ts +117 -0
- package/src/mods/uix/compile.test.ts +228 -0
- package/src/mods/uix/compile.ts +110 -0
- package/src/mods/uix/jsx-parser.test.ts +554 -0
- package/src/mods/uix/jsx-parser.ts +489 -0
- package/src/mods/uix/lazy-load.test.ts +261 -0
- package/src/mods/uix/uix-repomix.md +3509 -0
- package/src/mods/uix/verify.ts +68 -0
- package/src/schema/CLAUDE.md +13 -0
- package/src/schema/catalog.ts +101 -0
- package/src/schema/extract-schemas.test.ts +84 -0
- package/src/schema/extract-schemas.ts +462 -0
- package/src/schema/generated/autostart.json +44 -0
- package/src/schema/generated/board.column.json +25 -0
- package/src/schema/generated/board.task.json +147 -0
- package/src/schema/generated/brahman.action.back.json +12 -0
- package/src/schema/generated/brahman.action.broadcast.json +31 -0
- package/src/schema/generated/brahman.action.call.json +57 -0
- package/src/schema/generated/brahman.action.emittext.json +23 -0
- package/src/schema/generated/brahman.action.eval.json +23 -0
- package/src/schema/generated/brahman.action.file.json +28 -0
- package/src/schema/generated/brahman.action.forward.json +29 -0
- package/src/schema/generated/brahman.action.getvalue.json +28 -0
- package/src/schema/generated/brahman.action.ifelse.json +42 -0
- package/src/schema/generated/brahman.action.keywordselect.json +46 -0
- package/src/schema/generated/brahman.action.message.json +127 -0
- package/src/schema/generated/brahman.action.onerror.json +29 -0
- package/src/schema/generated/brahman.action.page.json +22 -0
- package/src/schema/generated/brahman.action.params.json +36 -0
- package/src/schema/generated/brahman.action.question.json +43 -0
- package/src/schema/generated/brahman.action.remove.json +12 -0
- package/src/schema/generated/brahman.action.resethistory.json +12 -0
- package/src/schema/generated/brahman.action.resetsession.json +12 -0
- package/src/schema/generated/brahman.action.selectlang.json +20 -0
- package/src/schema/generated/brahman.action.setvalue.json +27 -0
- package/src/schema/generated/brahman.action.tag.json +27 -0
- package/src/schema/generated/brahman.bot.json +68 -0
- package/src/schema/generated/brahman.page.json +25 -0
- package/src/schema/generated/brahman.session.json +29 -0
- package/src/schema/generated/brahman.user.json +58 -0
- package/src/schema/generated/cafe.contact.json +56 -0
- package/src/schema/generated/cafe.mail.json +29 -0
- package/src/schema/generated/default.json +15 -0
- package/src/schema/generated/doc.page.json +23 -0
- package/src/schema/generated/examples.demo.generator.json +16 -0
- package/src/schema/generated/examples.demo.sensor.json +35 -0
- package/src/schema/generated/groups.json +20 -0
- package/src/schema/generated/launcher.json +91 -0
- package/src/schema/generated/mcp.server.json +15 -0
- package/src/schema/generated/mindmap.map.json +22 -0
- package/src/schema/generated/sim.agent.json +24 -0
- package/src/schema/generated/sim.ai.json +24 -0
- package/src/schema/generated/sim.config.json +38 -0
- package/src/schema/generated/sim.descriptive.json +26 -0
- package/src/schema/generated/sim.events.json +47 -0
- package/src/schema/generated/sim.item.json +20 -0
- package/src/schema/generated/sim.memory.json +17 -0
- package/src/schema/generated/sim.nearby.json +17 -0
- package/src/schema/generated/sim.position.json +25 -0
- package/src/schema/generated/sim.round.json +64 -0
- package/src/schema/generated/sim.world.json +32 -0
- package/src/schema/generated/t.agent.port.json +74 -0
- package/src/schema/generated/t.llm.json +20 -0
- package/src/schema/generated/t.mod.json +27 -0
- package/src/schema/generated/t3d.animator.json +46 -0
- package/src/schema/generated/t3d.audio.json +58 -0
- package/src/schema/generated/t3d.camera.json +50 -0
- package/src/schema/generated/t3d.collider.json +84 -0
- package/src/schema/generated/t3d.light.json +90 -0
- package/src/schema/generated/t3d.line.json +47 -0
- package/src/schema/generated/t3d.lod.json +28 -0
- package/src/schema/generated/t3d.material.json +131 -0
- package/src/schema/generated/t3d.mesh.json +65 -0
- package/src/schema/generated/t3d.object.json +64 -0
- package/src/schema/generated/t3d.particles.json +109 -0
- package/src/schema/generated/t3d.rigidbody.json +81 -0
- package/src/schema/generated/t3d.scene.json +7 -0
- package/src/schema/generated/t3d.script.json +23 -0
- package/src/schema/generated/t3d.text.json +86 -0
- package/src/schema/generated/t3d.trail.json +45 -0
- package/src/schema/generated/task.json +96 -0
- package/src/schema/generated/test.fixture.json +43 -0
- package/src/schema/generated/ticker.config.json +43 -0
- package/src/schema/generated/ticker.price.json +20 -0
- package/src/schema/generated/todo.item.json +25 -0
- package/src/schema/generated/todo.list.json +33 -0
- package/src/schema/generated/treenity.system.json +259 -0
- package/src/schema/generated/whisper.audio.json +25 -0
- package/src/schema/generated/whisper.checklist.json +17 -0
- package/src/schema/generated/whisper.config.json +30 -0
- package/src/schema/generated/whisper.inbox.json +24 -0
- package/src/schema/generated/whisper.meta.json +35 -0
- package/src/schema/generated/whisper.text.json +16 -0
- package/src/schema/load.ts +24 -0
- package/src/schema/schema.test.ts +86 -0
- package/src/schema/test-fixture.types.ts +21 -0
- package/src/schema/test-opaque.ts +42 -0
- package/src/schema/types.ts +33 -0
- package/src/server/CLAUDE.md +26 -0
- package/src/server/actions.test.ts +272 -0
- package/src/server/actions.ts +274 -0
- package/src/server/agent-sub.test.ts +90 -0
- package/src/server/agent.test.ts +305 -0
- package/src/server/agent.ts +17 -0
- package/src/server/api.test.ts +454 -0
- package/src/server/auth.test.ts +441 -0
- package/src/server/auth.ts +386 -0
- package/src/server/client.ts +24 -0
- package/src/server/conditions.test.ts +128 -0
- package/src/server/cookies.ts +25 -0
- package/src/server/coverage.test.ts +827 -0
- package/src/server/doc-index.ts +286 -0
- package/src/server/e2e.test.ts +966 -0
- package/src/server/errors.ts +11 -0
- package/src/server/factory.ts +99 -0
- package/src/server/main.ts +56 -0
- package/src/server/mcp.ts +326 -0
- package/src/server/migrate.test.ts +123 -0
- package/src/server/migrate.ts +62 -0
- package/src/server/mod-catalog.ts +59 -0
- package/src/server/mods-mount.ts +179 -0
- package/src/server/mount-adapters.ts +82 -0
- package/src/server/mount.parametrized.test.ts +52 -0
- package/src/server/mount.query.test.ts +127 -0
- package/src/server/mount.test.ts +497 -0
- package/src/server/mount.ts +208 -0
- package/src/server/prefab.test.ts +415 -0
- package/src/server/prefab.ts +104 -0
- package/src/server/seed/index.ts +24 -0
- package/src/server/server.ts +153 -0
- package/src/server/stress.test.ts +844 -0
- package/src/server/sub.test.ts +55 -0
- package/src/server/sub.ts +224 -0
- package/src/server/trpc.ts +369 -0
- package/src/server/types-mount.ts +142 -0
- package/src/server/validate.test.ts +91 -0
- package/src/server/validate.ts +22 -0
- package/src/server/volatile.test.ts +140 -0
- package/src/server/volatile.ts +32 -0
- package/src/server/watch.test.ts +594 -0
- package/src/server/watch.ts +202 -0
- package/src/server/workflow.test.ts +82 -0
- package/src/tree/CLAUDE.md +13 -0
- package/src/tree/cache.test.ts +213 -0
- package/src/tree/cache.ts +51 -0
- package/src/tree/fs.test.ts +247 -0
- package/src/tree/fs.ts +251 -0
- package/src/tree/index.test.ts +164 -0
- package/src/tree/index.ts +216 -0
- package/src/tree/inflight.ts +15 -0
- package/src/tree/json-codec.ts +16 -0
- package/src/tree/mimefs.test.ts +289 -0
- package/src/tree/mimefs.ts +142 -0
- package/src/tree/mongo.ts +125 -0
- package/src/tree/patch.test.ts +192 -0
- package/src/tree/patch.ts +133 -0
- package/src/tree/query.test.ts +110 -0
- package/src/tree/query.ts +70 -0
- package/src/tree/repath.test.ts +86 -0
- package/src/tree/repath.ts +53 -0
- package/src/tree-chain.test.ts +723 -0
- package/src/tree-chain.ts +144 -0
- package/src/tree.ts +1 -0
- package/src/uri.test.ts +86 -0
- package/src/uri.ts +82 -0
- package/CHANGELOG.md +0 -305
- package/README.md +0 -18
- package/dist/context.d.ts +0 -41
- package/dist/context.d.ts.map +0 -1
- package/dist/context.mjs +0 -81
- package/dist/context.mjs.map +0 -1
- package/dist/contexts/node-engine.d.ts +0 -12
- package/dist/contexts/node-engine.d.ts.map +0 -1
- package/dist/contexts/node-engine.mjs +0 -7
- package/dist/contexts/node-engine.mjs.map +0 -1
- package/dist/contexts/noflo/types.d.ts +0 -20
- package/dist/contexts/noflo/types.d.ts.map +0 -1
- package/dist/contexts/object.d.ts +0 -11
- package/dist/contexts/object.d.ts.map +0 -1
- package/dist/contexts/object.mjs +0 -15
- package/dist/contexts/object.mjs.map +0 -1
- package/dist/contexts/proto.d.ts +0 -11
- package/dist/contexts/proto.d.ts.map +0 -1
- package/dist/contexts/proto.mjs +0 -7
- package/dist/contexts/proto.mjs.map +0 -1
- package/dist/contexts/react-context.d.ts +0 -21
- package/dist/contexts/react-context.d.ts.map +0 -1
- package/dist/contexts/react-context.mjs +0 -24
- package/dist/contexts/react-context.mjs.map +0 -1
- package/dist/contexts/service.mjs +0 -7
- package/dist/contexts/service.mjs.map +0 -1
- package/dist/get-type-cache.d.ts +0 -2
- package/dist/get-type-cache.d.ts.map +0 -1
- package/dist/get-type-cache.mjs +0 -7
- package/dist/get-type-cache.mjs.map +0 -1
- package/dist/index.d.ts +0 -13
- package/dist/index.d.ts.map +0 -1
- package/dist/index.mjs +0 -10
- package/dist/index.mjs.map +0 -1
- package/dist/link/link.d.ts +0 -25
- package/dist/link/link.d.ts.map +0 -1
- package/dist/link/link.mjs +0 -72
- package/dist/link/link.mjs.map +0 -1
- package/dist/link/link.test.d.ts +0 -2
- package/dist/link/link.test.d.ts.map +0 -1
- package/dist/loading.d.ts +0 -9
- package/dist/loading.d.ts.map +0 -1
- package/dist/meta-type.d.ts +0 -58
- package/dist/meta-type.d.ts.map +0 -1
- package/dist/meta-type.mjs +0 -104
- package/dist/meta-type.mjs.map +0 -1
- package/dist/meta.d.ts +0 -20
- package/dist/meta.d.ts.map +0 -1
- package/dist/meta.mjs +0 -16
- package/dist/meta.mjs.map +0 -1
- package/dist/node/index.d.ts +0 -2
- package/dist/node/index.d.ts.map +0 -1
- package/dist/node/types.d.ts +0 -37
- package/dist/node/types.d.ts.map +0 -1
- package/dist/test/context.test.d.ts +0 -2
- package/dist/test/context.test.d.ts.map +0 -1
- package/dist/types.d.ts +0 -14
- package/dist/types.d.ts.map +0 -1
- package/dist/types.mjs +0 -16
- package/dist/types.mjs.map +0 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Treenity Module Discovery
|
|
2
|
+
// npm: scan node_modules for packages with "treenity" field
|
|
3
|
+
// local: scan dir for subdirs with index.ts exporting defineMod()
|
|
4
|
+
|
|
5
|
+
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
import type { ModManifest, TreenityMod } from './types';
|
|
8
|
+
|
|
9
|
+
// ── npm discovery ──
|
|
10
|
+
|
|
11
|
+
export async function discoverMods(nodeModulesPath: string): Promise<ModManifest[]> {
|
|
12
|
+
const results: ModManifest[] = [];
|
|
13
|
+
let entries: string[];
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
entries = await readdir(nodeModulesPath);
|
|
17
|
+
} catch {
|
|
18
|
+
return results;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
for (const entry of entries) {
|
|
22
|
+
if (entry.startsWith('.')) continue;
|
|
23
|
+
|
|
24
|
+
// Scoped packages: @scope/pkg
|
|
25
|
+
if (entry.startsWith('@')) {
|
|
26
|
+
let scoped: string[];
|
|
27
|
+
try {
|
|
28
|
+
scoped = await readdir(join(nodeModulesPath, entry));
|
|
29
|
+
} catch { continue; }
|
|
30
|
+
|
|
31
|
+
for (const sub of scoped) {
|
|
32
|
+
const m = await readManifest(join(nodeModulesPath, entry, sub));
|
|
33
|
+
if (m) results.push(m);
|
|
34
|
+
}
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const m = await readManifest(join(nodeModulesPath, entry));
|
|
39
|
+
if (m) results.push(m);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return results;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function readManifest(packageDir: string): Promise<ModManifest | null> {
|
|
46
|
+
try {
|
|
47
|
+
const raw = await readFile(join(packageDir, 'package.json'), 'utf-8');
|
|
48
|
+
const pkg = JSON.parse(raw);
|
|
49
|
+
if (!pkg.treenity) return null;
|
|
50
|
+
|
|
51
|
+
const t = pkg.treenity;
|
|
52
|
+
return {
|
|
53
|
+
name: t.name ?? pkg.name,
|
|
54
|
+
version: t.version ?? pkg.version ?? '0.0.0',
|
|
55
|
+
types: t.types,
|
|
56
|
+
dependencies: t.dependencies,
|
|
57
|
+
server: t.server,
|
|
58
|
+
client: t.client,
|
|
59
|
+
seed: t.seed,
|
|
60
|
+
packagePath: packageDir,
|
|
61
|
+
};
|
|
62
|
+
} catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ── Local discovery (server-side, dynamic import) ──
|
|
68
|
+
|
|
69
|
+
export async function discoverLocalMods(modsDir: string): Promise<TreenityMod[]> {
|
|
70
|
+
const results: TreenityMod[] = [];
|
|
71
|
+
let entries: import('node:fs').Dirent[];
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
entries = await readdir(modsDir, { withFileTypes: true });
|
|
75
|
+
} catch {
|
|
76
|
+
return results;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for (const entry of entries) {
|
|
80
|
+
if (!entry.isDirectory() || entry.name.startsWith('.')) continue;
|
|
81
|
+
|
|
82
|
+
const indexPath = join(modsDir, entry.name, 'index.ts');
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
await stat(indexPath);
|
|
86
|
+
} catch {
|
|
87
|
+
continue; // no index.ts — not a mod
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
const exported = await import(indexPath);
|
|
92
|
+
const mod = exported.default as TreenityMod;
|
|
93
|
+
if (mod?.name) results.push(mod);
|
|
94
|
+
} catch {
|
|
95
|
+
// bad index.ts — skip silently
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return results;
|
|
100
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Treenity Mods — документация
|
|
2
|
+
|
|
3
|
+
| # | Файл | Тема |
|
|
4
|
+
|---|------|------|
|
|
5
|
+
| 01 | [01-primitives.md](01-primitives.md) | Три примитива, структура мода, dev workflow |
|
|
6
|
+
| 02 | [02-core-api.md](02-core-api.md) | Core API: ноды, компоненты, ссылки, пути |
|
|
7
|
+
| 03 | [03-registry.md](03-registry.md) | Registry — система контекстов, fallback, introspection |
|
|
8
|
+
| 04 | [04-store.md](04-store.md) | Store: интерфейс, OCC, реализации, комбинаторы, query |
|
|
9
|
+
| 05 | [05-comp.md](05-comp.md) | registerComp, getCtx, needs, type-safe доступ, JSDoc→Schema |
|
|
10
|
+
| 06 | [06-actions.md](06-actions.md) | Экшены: execute/call, generator, вызов с клиента |
|
|
11
|
+
| 07 | [07-realtime.md](07-realtime.md) | Подписки, CDC, React хуки, рендер через контекст |
|
|
12
|
+
| 08 | [08-services.md](08-services.md) | Сервисы, автозапуск |
|
|
13
|
+
| 09 | [09-mounts.md](09-mounts.md) | Mount-адаптеры, query mounts |
|
|
14
|
+
| 10 | [10-acl.md](10-acl.md) | ACL, валидация, volatile, server pipeline |
|
|
15
|
+
| 11 | [11-server.md](11-server.md) | tRPC endpoints, MCP, seed |
|
|
16
|
+
| 12 | [12-conventions.md](12-conventions.md) | Naming, стили, архитектурные правила |
|
|
17
|
+
| 13 | [13-example.md](13-example.md) | Полный пример мода от начала до конца |
|
|
18
|
+
| 14 | [14-mod-format.md](14-mod-format.md) | npm-модули: формат, discovery, загрузка, optimistic updates |
|
|
19
|
+
| 15 | [15-documenting-types.md](15-documenting-types.md) | JSDoc-аннотации: теги, форматы, примеры, промпт для LLM |
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# 01 — Три примитива
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
Node = { $path, $type, ...components } // сущность в дереве
|
|
5
|
+
Component = { $type, ...data } // именованный аспект ноды
|
|
6
|
+
Context = register(type, context, handler) // поведение типа в контексте
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Нода — это `$path` + `$type` + произвольные компоненты. Компонент — именованное поле с `$type`. Контекст привязывает поведение (рендер, экшен, сервис) к типу.
|
|
10
|
+
|
|
11
|
+
Системные поля: `$path`, `$type`, `$rev` (OCC), `$owner`, `$acl`.
|
|
12
|
+
|
|
13
|
+
## Структура мода
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
src/mods/my-mod/
|
|
17
|
+
types.ts — registerComp() — классы компонентов, данные + экшены
|
|
18
|
+
action.ts — register(type, 'action:name', handler) — node-level экшены
|
|
19
|
+
schemas.ts — register(type, 'schema', () => ({...})) — JSON Schema для UI
|
|
20
|
+
view.tsx — register(type, 'react', Component) — React-рендеры
|
|
21
|
+
service.ts — register(type, 'service', handler) — фоновый сервис
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Регистрация:
|
|
25
|
+
- Сервер: добавь импорт в `src/mods/index.ts`
|
|
26
|
+
- Фронтенд: добавь импорт в `src/mods/views.ts` + `registerViews()`
|
|
27
|
+
|
|
28
|
+
## Dev workflow
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm run schema # извлечь JSON Schema из JSDoc → dist/schema/
|
|
32
|
+
npm test # tsx --test src/**/*.test.ts
|
|
33
|
+
npm run dev:server # tsx --watch src/server/index.ts (порт 3001)
|
|
34
|
+
npm run dev:front # vite (React-фронт)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Seed-данные: `data/base/` (git-tracked), runtime-данные: `data/work/` (gitignored).
|
|
38
|
+
Overlay: work поверх base — записи идут в work, чтение fallback на base.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# 02 — Core API
|
|
2
|
+
|
|
3
|
+
## Типы
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import {
|
|
7
|
+
type NodeData, // { $path, $type, $rev?, $owner?, $acl?, ...components }
|
|
8
|
+
type ComponentData, // { $type, $acl?, ...data }
|
|
9
|
+
type GroupPerm, // { g: string, p: number }
|
|
10
|
+
type Ref, // { $type: 'ref', $ref: string }
|
|
11
|
+
R, W, A, S, // ACL bits: Read=1, Write=2, Admin=4, Subscribe=8
|
|
12
|
+
} from '#core';
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Создание нод
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { createNode } from '#core';
|
|
19
|
+
|
|
20
|
+
const node = createNode('/tasks/1', 'task', {
|
|
21
|
+
metadata: { $type: 'metadata', title: 'Hello' },
|
|
22
|
+
status: { $type: 'status', value: 'draft' },
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Работа с компонентами
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { getComponent, setComponent, removeComponent, getComponentsByType } from '#core';
|
|
30
|
+
|
|
31
|
+
getComponent(node, 'metadata'); // → { $type, title } | undefined
|
|
32
|
+
getComponentsByType(node, 'status'); // → [['status', { $type, value }]]
|
|
33
|
+
setComponent(node, 'status', { $type: 'status', value: 'done' });
|
|
34
|
+
removeComponent(node, 'status'); // → boolean
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Ссылки
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { ref, isRef } from '#core';
|
|
41
|
+
import { resolveRef } from '#tree';
|
|
42
|
+
|
|
43
|
+
const r = ref('/tasks/1'); // { $type: "ref", $ref: "/tasks/1" }
|
|
44
|
+
isRef(r); // true
|
|
45
|
+
const target = await resolveRef(store, refNode); // → NodeData
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Пути
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { dirname, basename, join, isChildPath } from '#core';
|
|
52
|
+
|
|
53
|
+
dirname('/a/b'); // → "/a"
|
|
54
|
+
basename('/a/b'); // → "b"
|
|
55
|
+
join('/a', 'b'); // → "/a/b"
|
|
56
|
+
isChildPath('/a', '/a/b'); // → true (direct child)
|
|
57
|
+
isChildPath('/a', '/a/b/c'); // → false (not direct)
|
|
58
|
+
isChildPath('/a', '/a/b/c', false); // → true (any depth)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Утилиты типов
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import { isComponent, isOfType } from '#core';
|
|
65
|
+
|
|
66
|
+
isComponent(value); // value is ComponentData
|
|
67
|
+
isOfType<T>(value, 'my-type'); // value is ComponentData<T>
|
|
68
|
+
```
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# 03 — Registry — система контекстов
|
|
2
|
+
|
|
3
|
+
Единственный механизм расширения. `register(type, context, handler)` — привязать обработчик к типу в контексте.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { register, resolve, render } from '#core';
|
|
7
|
+
|
|
8
|
+
// Регистрация
|
|
9
|
+
register('task', 'schema', () => ({ properties: { title: { type: 'string' } } }));
|
|
10
|
+
register('task', 'react', MyComponent);
|
|
11
|
+
register('task', 'text', (data) => `Task: ${data.title}`);
|
|
12
|
+
|
|
13
|
+
// Резолв (fallback: exact → default@same-ctx → strip suffix → recurse → null)
|
|
14
|
+
resolve('task', 'react:compact'); // → task@react:compact → default@react:compact → task@react → default@react → null
|
|
15
|
+
|
|
16
|
+
// Рендер
|
|
17
|
+
render(component, 'text'); // вызывает handler(component)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**Sealed registry:** дублирование `register()` молча игнорируется (HMR-safe). Переопределить нельзя. Расширяй через новые контексты (`react:mobile`), а не замену.
|
|
21
|
+
|
|
22
|
+
## Introspection
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { getRegisteredTypes, getContextsForType, getMeta } from '#core';
|
|
26
|
+
|
|
27
|
+
getRegisteredTypes('schema'); // → ['task', 'order', ...]
|
|
28
|
+
getContextsForType('task'); // → ['schema', 'react', 'text', 'action:publish']
|
|
29
|
+
getMeta('task', 'schema'); // → metadata объект или null
|
|
30
|
+
```
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# 04 — Store — доступ к данным
|
|
2
|
+
|
|
3
|
+
## Интерфейс
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { type Store, type Page, type ChildrenOpts } from '#tree';
|
|
7
|
+
|
|
8
|
+
store.get(path); // → NodeData | undefined
|
|
9
|
+
store.set(node); // upsert (OCC по $rev)
|
|
10
|
+
store.remove(path); // → boolean
|
|
11
|
+
store.getChildren(path, { depth, limit, offset }); // → Page<NodeData>
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`Page<T> = { items: T[], total: number }`
|
|
15
|
+
|
|
16
|
+
## OCC (Optimistic Concurrency Control)
|
|
17
|
+
|
|
18
|
+
Если нода имеет `$rev`, store.set() проверяет совпадение и бросает ошибку при конфликте:
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
const node = await store.get('/tasks/1');
|
|
22
|
+
node.status.value = 'done';
|
|
23
|
+
await store.set(node); // если $rev изменился — OptimisticConcurrencyError
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Реализации
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { createMemoryStore } from '#tree';
|
|
30
|
+
import { createFsStore } from '#tree/fs';
|
|
31
|
+
import { createMongoStore } from '#tree/mongo';
|
|
32
|
+
|
|
33
|
+
const mem = createMemoryStore();
|
|
34
|
+
const fs = await createFsStore('./data/base');
|
|
35
|
+
const mongo = await createMongoStore(uri, 'mydb', 'nodes');
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Комбинаторы
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { createOverlayStore, createFilterStore } from '#tree';
|
|
42
|
+
|
|
43
|
+
// Overlay: reads from upper first, writes go to upper only
|
|
44
|
+
const overlay = createOverlayStore(workStore, baseStore);
|
|
45
|
+
|
|
46
|
+
// Filter: routes set() по предикату (upper если true, lower если false)
|
|
47
|
+
const filtered = createFilterStore(hotStore, coldStore, (node) => node.$type === 'hot');
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Query Store (sift)
|
|
51
|
+
|
|
52
|
+
Виртуальная отфильтрованная проекция. Mongo-синтаксис через sift:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { createQueryStore } from '#tree/query';
|
|
56
|
+
|
|
57
|
+
const incoming = createQueryStore(
|
|
58
|
+
{ source: '/orders/data', match: { status: { value: 'incoming' } } },
|
|
59
|
+
parentStore,
|
|
60
|
+
);
|
|
61
|
+
// getChildren('/') → только ноды, где status.value === 'incoming'
|
|
62
|
+
```
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# 05 — registerComp — типизированные компоненты
|
|
2
|
+
|
|
3
|
+
Класс = схема полей + методы-экшены. Методы автоматически регистрируются как `action:{name}`.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { registerComp, type CompClass } from '#comp';
|
|
7
|
+
|
|
8
|
+
class Status {
|
|
9
|
+
value = 'draft';
|
|
10
|
+
|
|
11
|
+
publish() {
|
|
12
|
+
this.value = 'published';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
archive() {
|
|
16
|
+
this.value = 'archived';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
registerComp('order.status', Status);
|
|
21
|
+
// Автоматически: register('order.status', 'action:publish', handler)
|
|
22
|
+
// register('order.status', 'action:archive', handler)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## getCtx() — доступ к Store из методов класса
|
|
26
|
+
|
|
27
|
+
Методы класса получают `this` = Immer draft (компонент). Для доступа к store, ноде и AbortSignal используй `getCtx()`:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { getCtx, registerComp } from '#comp';
|
|
31
|
+
import { join, type NodeData } from '#core';
|
|
32
|
+
|
|
33
|
+
class Portfolio {
|
|
34
|
+
risk = 0.5;
|
|
35
|
+
|
|
36
|
+
setRisk(data: { value: number }) {
|
|
37
|
+
this.risk = data.value; // простая мутация — getCtx не нужен
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async rebalance() {
|
|
41
|
+
const { node, store } = getCtx();
|
|
42
|
+
const { items } = await store.getChildren(join(node.$path, 'positions'));
|
|
43
|
+
|
|
44
|
+
for (const pos of items) {
|
|
45
|
+
await store.set(pos);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return { rebalanced: items.length };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async selfDestruct() {
|
|
52
|
+
const { node, store } = getCtx();
|
|
53
|
+
await store.remove(node.$path);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
registerComp('portfolio', Portfolio);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Как это работает:** перед вызовом метода система ставит контекст в глобальную переменную. JS однопоточный — между установкой и первой синхронной строкой метода ничто не вклинится, поэтому `getCtx()` всегда захватывает правильный контекст.
|
|
61
|
+
|
|
62
|
+
**CompCtx:**
|
|
63
|
+
```ts
|
|
64
|
+
type CompCtx = {
|
|
65
|
+
node: NodeData; // полная нода (Immer draft в executeAction)
|
|
66
|
+
store: Store; // реактивный store
|
|
67
|
+
signal: AbortSignal; // таймаут 30с
|
|
68
|
+
};
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Правило:** если метод только мутирует `this` — getCtx не нужен. Если нужен store/node — `const ctx = getCtx()` на первой строке (до любого await).
|
|
72
|
+
|
|
73
|
+
## Needs — зависимости от соседних компонентов
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
class PublishedDate {
|
|
77
|
+
date = '';
|
|
78
|
+
|
|
79
|
+
stamp(data: unknown, siblings: Record<string, ComponentData>) {
|
|
80
|
+
this.date = new Date().toISOString();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
registerComp('published-date', PublishedDate, { needs: ['status'] });
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Type-safe доступ к компонентам
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
import { getComp, setComp, newComp, getCompField } from '#comp';
|
|
91
|
+
|
|
92
|
+
const status = getComp(node, Status); // → ComponentData<Status> | undefined
|
|
93
|
+
setComp(node, Status, { value: 'done' }); // обновляет поля
|
|
94
|
+
const fresh = newComp(Status, { value: 'new' }); // создаёт { $type: 'order.status', value: 'new' }
|
|
95
|
+
|
|
96
|
+
const [fieldName, comp] = getCompField(node, Status)!; // → ['status', {...}]
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## JSDoc → JSON Schema
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
class BlockHero {
|
|
103
|
+
/** @title Заголовок @description Главный заголовок страницы */
|
|
104
|
+
title = '';
|
|
105
|
+
/** @title Картинка @format image */
|
|
106
|
+
image = '';
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
registerComp('block.hero', BlockHero);
|
|
110
|
+
// npm run schema → dist/schema/block.hero.json
|
|
111
|
+
```
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# 06 — Экшены
|
|
2
|
+
|
|
3
|
+
Экшен — метод класса компонента. Сервер исполняет его через Immer draft, патчи
|
|
4
|
+
автоматически сохраняются. Если данные не менялись — store.set() не вызывается.
|
|
5
|
+
|
|
6
|
+
## Шаг 1: определи экшены как методы класса
|
|
7
|
+
|
|
8
|
+
```ts
|
|
9
|
+
import { registerComp } from '#comp';
|
|
10
|
+
|
|
11
|
+
export class OrderStatus {
|
|
12
|
+
value: 'incoming' | 'kitchen' | 'ready' = 'incoming';
|
|
13
|
+
|
|
14
|
+
advance() {
|
|
15
|
+
// this — Immer draft компонента
|
|
16
|
+
if (this.value === 'incoming') this.value = 'kitchen';
|
|
17
|
+
else if (this.value === 'kitchen') this.value = 'ready';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
registerComp('order.status', OrderStatus);
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Всё. `registerComp` автоматически регистрирует `action:advance` из метода.
|
|
25
|
+
|
|
26
|
+
## Шаг 2: вызов из React-вьюшки
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import { useComp } from '#front/hooks';
|
|
30
|
+
import { OrderStatus } from './types';
|
|
31
|
+
|
|
32
|
+
function OrderCard({ path }: { path: string }) {
|
|
33
|
+
const status = useComp(path, OrderStatus);
|
|
34
|
+
// status.value — live данные из кэша (реактивно)
|
|
35
|
+
// status.advance() — вызывает trpc.execute, получает ответ
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<button onClick={() => status.advance()}>
|
|
39
|
+
{status.value} →
|
|
40
|
+
</button>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`useComp(path, Class, key?)` — одна точка для данных и действий.
|
|
46
|
+
- `key` нужен только если на ноде несколько компонентов одного `$type`.
|
|
47
|
+
|
|
48
|
+
## Шаг 3: вызов из сервиса / серверного кода
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { createServerNodeClient } from '#server/actions';
|
|
52
|
+
import { OrderStatus } from '../orders/types';
|
|
53
|
+
|
|
54
|
+
register('my.service', 'service', async (node, ctx) => {
|
|
55
|
+
const nc = createServerNodeClient(ctx.store);
|
|
56
|
+
|
|
57
|
+
await nc('/orders/123').get(OrderStatus).advance();
|
|
58
|
+
// Typed: IDE подсказывает методы и аргументы
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`key` можно опустить: если ключ поля совпадает с последним сегментом `$type`
|
|
63
|
+
(`'order.status'` → `'status'`), сканирование находит компонент автоматически.
|
|
64
|
+
|
|
65
|
+
## Методы с аргументами
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
export class PultConfig {
|
|
69
|
+
risk = 0.5;
|
|
70
|
+
|
|
71
|
+
setRisk(data: { value: number }) {
|
|
72
|
+
this.risk = Math.max(0, Math.min(1, data.value));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
// React:
|
|
79
|
+
const cfg = useComp(path, PultConfig);
|
|
80
|
+
<Fader onChange={v => cfg.setRisk({ value: v })} />
|
|
81
|
+
|
|
82
|
+
// Сервис:
|
|
83
|
+
await nc(path).get(PultConfig).setRisk({ value: 0.1 });
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Сигнатура = порты + параметры
|
|
87
|
+
|
|
88
|
+
Тип `data`-аргумента метода — единый источник правды для двух контекстов:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
class Invoice {
|
|
92
|
+
static $type = 'billing.invoice'
|
|
93
|
+
|
|
94
|
+
async charge(data: { amount: number, account: Account, user?: User }) {
|
|
95
|
+
data.account.debit(data.amount)
|
|
96
|
+
data.user?.notify('charged')
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
| В коде | В визуальном редакторе |
|
|
102
|
+
|--------|----------------------|
|
|
103
|
+
| `amount: number` — параметр, передаётся при вызове | Поле ввода на кубике |
|
|
104
|
+
| `account: Account` — typed значение | **Порт** — входной разъём типа Account, тянешь провод |
|
|
105
|
+
| `user?: User` — optional параметр | **Опциональный порт** — можно не подключать |
|
|
106
|
+
|
|
107
|
+
**Вызов из кода** — обычный typed call:
|
|
108
|
+
```ts
|
|
109
|
+
invoice.charge({ amount: 10, account: user.account })
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Компиляция графа** — визуальный редактор собирает значения с подключённых портов:
|
|
113
|
+
```ts
|
|
114
|
+
// wired connections → data object:
|
|
115
|
+
invoice.charge({
|
|
116
|
+
amount: amountNode.value,
|
|
117
|
+
account: getComp(acmeNode, Account),
|
|
118
|
+
})
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Одна TypeScript-сигнатура, два мира. TypeScript проверяет типы при компиляции,
|
|
122
|
+
JSON Schema генерируется для AI/валидации. Без отдельного DSL для портов.
|
|
123
|
+
|
|
124
|
+
## Async-методы и доступ к store
|
|
125
|
+
|
|
126
|
+
> **Правило:** `getCtx()` вызывай только синхронно на первой строке метода — до первого `await`/`yield`.
|
|
127
|
+
> После `await` контекст уже не валиден (async stack ушёл).
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
import { getCtx } from '#comp';
|
|
133
|
+
|
|
134
|
+
export class PultConfig {
|
|
135
|
+
async rebalance() {
|
|
136
|
+
const { node, store } = getCtx(); // ТОЛЬКО на первой строке — до первого await
|
|
137
|
+
|
|
138
|
+
const { items: markets } = await store.getChildren(`${node.$path}/markets`);
|
|
139
|
+
for (const m of markets) {
|
|
140
|
+
// ...
|
|
141
|
+
}
|
|
142
|
+
return { rebalanced: markets.length };
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Generator-экшены — стримят результаты клиенту
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
export class Builder {
|
|
151
|
+
async *build(data: { count: number }) {
|
|
152
|
+
const { node, store, signal } = getCtx(); // ТОЛЬКО здесь — до любого await/yield
|
|
153
|
+
|
|
154
|
+
for (let i = 0; i < data.count; i++) {
|
|
155
|
+
if (signal.aborted) return;
|
|
156
|
+
const item = await buildItem(i);
|
|
157
|
+
await store.set(item);
|
|
158
|
+
yield item; // нода → клиент кладёт в кэш
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
// Подписка на стрим:
|
|
166
|
+
trpc.streamAction.subscribe({ path, action: 'build', data: { count: 10 } }, {
|
|
167
|
+
onData(item) { /* nodes → cache */ },
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Справка: низкоуровневые вызовы
|
|
174
|
+
|
|
175
|
+
Используй только если `useComp`/`createServerNodeClient` не подходят
|
|
176
|
+
(generic Inspector, MCP, внешние интеграции).
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
// Прямой вызов (type scan без key):
|
|
180
|
+
await executeAction(store, path, 'order.status', undefined, 'advance');
|
|
181
|
+
|
|
182
|
+
// С конкретным key:
|
|
183
|
+
await executeAction(store, path, 'order.status', 'status', 'advance');
|
|
184
|
+
|
|
185
|
+
// Node-level (без компонента):
|
|
186
|
+
await executeAction(store, path, undefined, undefined, 'doStuff');
|
|
187
|
+
|
|
188
|
+
// tRPC напрямую:
|
|
189
|
+
trpc.execute.mutate({ path, type: 'order.status', action: 'advance' });
|
|
190
|
+
trpc.execute.mutate({ path, type: 'order.status', key: 'status', action: 'advance' });
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Resolution: key → node[key] + verify $type; type only → findCompByType scan; neither → node.$type scan.
|