opentasks 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +344 -1
- package/dist/__tests__/cli-tools.test.d.ts +8 -0
- package/dist/__tests__/cli-tools.test.d.ts.map +1 -0
- package/dist/__tests__/cli-tools.test.js +546 -0
- package/dist/__tests__/cli-tools.test.js.map +1 -0
- package/dist/__tests__/cli.test.d.ts +5 -0
- package/dist/__tests__/cli.test.d.ts.map +1 -0
- package/dist/__tests__/cli.test.js +77 -0
- package/dist/__tests__/cli.test.js.map +1 -0
- package/dist/__tests__/p1-p3-gaps.test.d.ts +2 -0
- package/dist/__tests__/p1-p3-gaps.test.d.ts.map +1 -0
- package/dist/__tests__/p1-p3-gaps.test.js +463 -0
- package/dist/__tests__/p1-p3-gaps.test.js.map +1 -0
- package/dist/cli.d.ts +19 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +702 -23
- package/dist/cli.js.map +1 -1
- package/dist/client/__tests__/client-crud.test.d.ts +7 -0
- package/dist/client/__tests__/client-crud.test.d.ts.map +1 -0
- package/dist/client/__tests__/client-crud.test.js +404 -0
- package/dist/client/__tests__/client-crud.test.js.map +1 -0
- package/dist/client/__tests__/client.test.d.ts +5 -0
- package/dist/client/__tests__/client.test.d.ts.map +1 -0
- package/dist/client/__tests__/client.test.js +518 -0
- package/dist/client/__tests__/client.test.js.map +1 -0
- package/dist/client/client.d.ts +228 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +393 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/index.d.ts +11 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +9 -0
- package/dist/client/index.js.map +1 -0
- package/dist/config/__tests__/defaults.test.d.ts +2 -0
- package/dist/config/__tests__/defaults.test.d.ts.map +1 -0
- package/dist/config/__tests__/defaults.test.js +57 -0
- package/dist/config/__tests__/defaults.test.js.map +1 -0
- package/dist/config/__tests__/env.test.d.ts +2 -0
- package/dist/config/__tests__/env.test.d.ts.map +1 -0
- package/dist/config/__tests__/env.test.js +136 -0
- package/dist/config/__tests__/env.test.js.map +1 -0
- package/dist/config/__tests__/index.test.d.ts +2 -0
- package/dist/config/__tests__/index.test.d.ts.map +1 -0
- package/dist/config/__tests__/index.test.js +113 -0
- package/dist/config/__tests__/index.test.js.map +1 -0
- package/dist/config/__tests__/loader.test.d.ts +2 -0
- package/dist/config/__tests__/loader.test.d.ts.map +1 -0
- package/dist/config/__tests__/loader.test.js +128 -0
- package/dist/config/__tests__/loader.test.js.map +1 -0
- package/dist/config/__tests__/merge.test.d.ts +2 -0
- package/dist/config/__tests__/merge.test.d.ts.map +1 -0
- package/dist/config/__tests__/merge.test.js +79 -0
- package/dist/config/__tests__/merge.test.js.map +1 -0
- package/dist/config/__tests__/schema.test.d.ts +2 -0
- package/dist/config/__tests__/schema.test.d.ts.map +1 -0
- package/dist/config/__tests__/schema.test.js +300 -0
- package/dist/config/__tests__/schema.test.js.map +1 -0
- package/dist/config/defaults.d.ts +13 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +15 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/env.d.ts +14 -0
- package/dist/config/env.d.ts.map +1 -0
- package/dist/config/env.js +130 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/errors.d.ts +21 -0
- package/dist/config/errors.d.ts.map +1 -0
- package/dist/config/errors.js +30 -0
- package/dist/config/errors.js.map +1 -0
- package/dist/config/index.d.ts +21 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +41 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +8 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +87 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/merge.d.ts +12 -0
- package/dist/config/merge.d.ts.map +1 -0
- package/dist/config/merge.js +54 -0
- package/dist/config/merge.js.map +1 -0
- package/dist/config/schema.d.ts +644 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +491 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/__tests__/conditional-redirects.test.d.ts +2 -0
- package/dist/core/__tests__/conditional-redirects.test.d.ts.map +1 -0
- package/dist/core/__tests__/conditional-redirects.test.js +83 -0
- package/dist/core/__tests__/conditional-redirects.test.js.map +1 -0
- package/dist/core/__tests__/connections.test.d.ts +2 -0
- package/dist/core/__tests__/connections.test.d.ts.map +1 -0
- package/dist/core/__tests__/connections.test.js +158 -0
- package/dist/core/__tests__/connections.test.js.map +1 -0
- package/dist/core/__tests__/hash.test.d.ts +2 -0
- package/dist/core/__tests__/hash.test.d.ts.map +1 -0
- package/dist/core/__tests__/hash.test.js +139 -0
- package/dist/core/__tests__/hash.test.js.map +1 -0
- package/dist/core/__tests__/id.test.d.ts +2 -0
- package/dist/core/__tests__/id.test.d.ts.map +1 -0
- package/dist/core/__tests__/id.test.js +142 -0
- package/dist/core/__tests__/id.test.js.map +1 -0
- package/dist/core/__tests__/location.test.d.ts +2 -0
- package/dist/core/__tests__/location.test.d.ts.map +1 -0
- package/dist/core/__tests__/location.test.js +77 -0
- package/dist/core/__tests__/location.test.js.map +1 -0
- package/dist/core/__tests__/merge-driver.test.d.ts +2 -0
- package/dist/core/__tests__/merge-driver.test.d.ts.map +1 -0
- package/dist/core/__tests__/merge-driver.test.js +218 -0
- package/dist/core/__tests__/merge-driver.test.js.map +1 -0
- package/dist/core/__tests__/redirects.test.d.ts +2 -0
- package/dist/core/__tests__/redirects.test.d.ts.map +1 -0
- package/dist/core/__tests__/redirects.test.js +123 -0
- package/dist/core/__tests__/redirects.test.js.map +1 -0
- package/dist/core/__tests__/resolve-location-target.test.d.ts +8 -0
- package/dist/core/__tests__/resolve-location-target.test.d.ts.map +1 -0
- package/dist/core/__tests__/resolve-location-target.test.js +303 -0
- package/dist/core/__tests__/resolve-location-target.test.js.map +1 -0
- package/dist/core/__tests__/uri.test.d.ts +2 -0
- package/dist/core/__tests__/uri.test.d.ts.map +1 -0
- package/dist/core/__tests__/uri.test.js +159 -0
- package/dist/core/__tests__/uri.test.js.map +1 -0
- package/dist/core/__tests__/worktree.test.d.ts +2 -0
- package/dist/core/__tests__/worktree.test.d.ts.map +1 -0
- package/dist/core/__tests__/worktree.test.js +120 -0
- package/dist/core/__tests__/worktree.test.js.map +1 -0
- package/dist/core/conditional-redirects.d.ts +42 -0
- package/dist/core/conditional-redirects.d.ts.map +1 -0
- package/dist/core/conditional-redirects.js +59 -0
- package/dist/core/conditional-redirects.js.map +1 -0
- package/dist/core/connections.d.ts +87 -0
- package/dist/core/connections.d.ts.map +1 -0
- package/dist/core/connections.js +160 -0
- package/dist/core/connections.js.map +1 -0
- package/dist/core/discover.d.ts +39 -0
- package/dist/core/discover.d.ts.map +1 -0
- package/dist/core/discover.js +136 -0
- package/dist/core/discover.js.map +1 -0
- package/dist/core/hash.d.ts +25 -0
- package/dist/core/hash.d.ts.map +1 -0
- package/dist/core/hash.js +62 -0
- package/dist/core/hash.js.map +1 -0
- package/dist/core/id.d.ts +79 -0
- package/dist/core/id.d.ts.map +1 -0
- package/dist/core/id.js +141 -0
- package/dist/core/id.js.map +1 -0
- package/dist/core/index.d.ts +15 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +24 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/location.d.ts +70 -0
- package/dist/core/location.d.ts.map +1 -0
- package/dist/core/location.js +121 -0
- package/dist/core/location.js.map +1 -0
- package/dist/core/merge-driver.d.ts +50 -0
- package/dist/core/merge-driver.d.ts.map +1 -0
- package/dist/core/merge-driver.js +258 -0
- package/dist/core/merge-driver.js.map +1 -0
- package/dist/core/redirects.d.ts +91 -0
- package/dist/core/redirects.d.ts.map +1 -0
- package/dist/core/redirects.js +113 -0
- package/dist/core/redirects.js.map +1 -0
- package/dist/core/uri.d.ts +105 -0
- package/dist/core/uri.d.ts.map +1 -0
- package/dist/core/uri.js +190 -0
- package/dist/core/uri.js.map +1 -0
- package/dist/core/worktree.d.ts +106 -0
- package/dist/core/worktree.d.ts.map +1 -0
- package/dist/core/worktree.js +394 -0
- package/dist/core/worktree.js.map +1 -0
- package/dist/daemon/__tests__/flush.test.d.ts +5 -0
- package/dist/daemon/__tests__/flush.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/flush.test.js +213 -0
- package/dist/daemon/__tests__/flush.test.js.map +1 -0
- package/dist/daemon/__tests__/integration.test.d.ts +7 -0
- package/dist/daemon/__tests__/integration.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/integration.test.js +276 -0
- package/dist/daemon/__tests__/integration.test.js.map +1 -0
- package/dist/daemon/__tests__/ipc.test.d.ts +5 -0
- package/dist/daemon/__tests__/ipc.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/ipc.test.js +314 -0
- package/dist/daemon/__tests__/ipc.test.js.map +1 -0
- package/dist/daemon/__tests__/lifecycle.test.d.ts +5 -0
- package/dist/daemon/__tests__/lifecycle.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/lifecycle.test.js +301 -0
- package/dist/daemon/__tests__/lifecycle.test.js.map +1 -0
- package/dist/daemon/__tests__/lock.test.d.ts +5 -0
- package/dist/daemon/__tests__/lock.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/lock.test.js +192 -0
- package/dist/daemon/__tests__/lock.test.js.map +1 -0
- package/dist/daemon/__tests__/methods/graph.test.d.ts +5 -0
- package/dist/daemon/__tests__/methods/graph.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/methods/graph.test.js +309 -0
- package/dist/daemon/__tests__/methods/graph.test.js.map +1 -0
- package/dist/daemon/__tests__/methods/provider.test.d.ts +7 -0
- package/dist/daemon/__tests__/methods/provider.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/methods/provider.test.js +181 -0
- package/dist/daemon/__tests__/methods/provider.test.js.map +1 -0
- package/dist/daemon/__tests__/methods/tools.test.d.ts +5 -0
- package/dist/daemon/__tests__/methods/tools.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/methods/tools.test.js +587 -0
- package/dist/daemon/__tests__/methods/tools.test.js.map +1 -0
- package/dist/daemon/__tests__/multi-location.test.d.ts +8 -0
- package/dist/daemon/__tests__/multi-location.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/multi-location.test.js +669 -0
- package/dist/daemon/__tests__/multi-location.test.js.map +1 -0
- package/dist/daemon/__tests__/registry.test.d.ts +5 -0
- package/dist/daemon/__tests__/registry.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/registry.test.js +208 -0
- package/dist/daemon/__tests__/registry.test.js.map +1 -0
- package/dist/daemon/__tests__/watcher.test.d.ts +5 -0
- package/dist/daemon/__tests__/watcher.test.d.ts.map +1 -0
- package/dist/daemon/__tests__/watcher.test.js +234 -0
- package/dist/daemon/__tests__/watcher.test.js.map +1 -0
- package/dist/daemon/entire-linker.d.ts +68 -0
- package/dist/daemon/entire-linker.d.ts.map +1 -0
- package/dist/daemon/entire-linker.js +439 -0
- package/dist/daemon/entire-linker.js.map +1 -0
- package/dist/daemon/entire-watcher.d.ts +66 -0
- package/dist/daemon/entire-watcher.d.ts.map +1 -0
- package/dist/daemon/entire-watcher.js +258 -0
- package/dist/daemon/entire-watcher.js.map +1 -0
- package/dist/daemon/factory.d.ts +59 -0
- package/dist/daemon/factory.d.ts.map +1 -0
- package/dist/daemon/factory.js +72 -0
- package/dist/daemon/factory.js.map +1 -0
- package/dist/daemon/flush.d.ts +51 -0
- package/dist/daemon/flush.d.ts.map +1 -0
- package/dist/daemon/flush.js +89 -0
- package/dist/daemon/flush.js.map +1 -0
- package/dist/daemon/index.d.ts +39 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +24 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/ipc.d.ts +97 -0
- package/dist/daemon/ipc.d.ts.map +1 -0
- package/dist/daemon/ipc.js +304 -0
- package/dist/daemon/ipc.js.map +1 -0
- package/dist/daemon/lifecycle.d.ts +85 -0
- package/dist/daemon/lifecycle.d.ts.map +1 -0
- package/dist/daemon/lifecycle.js +754 -0
- package/dist/daemon/lifecycle.js.map +1 -0
- package/dist/daemon/location-state.d.ts +85 -0
- package/dist/daemon/location-state.d.ts.map +1 -0
- package/dist/daemon/location-state.js +291 -0
- package/dist/daemon/location-state.js.map +1 -0
- package/dist/daemon/lock.d.ts +29 -0
- package/dist/daemon/lock.d.ts.map +1 -0
- package/dist/daemon/lock.js +131 -0
- package/dist/daemon/lock.js.map +1 -0
- package/dist/daemon/methods/__tests__/graph.test.d.ts +5 -0
- package/dist/daemon/methods/__tests__/graph.test.d.ts.map +1 -0
- package/dist/daemon/methods/__tests__/graph.test.js +274 -0
- package/dist/daemon/methods/__tests__/graph.test.js.map +1 -0
- package/dist/daemon/methods/__tests__/provider.test.d.ts +5 -0
- package/dist/daemon/methods/__tests__/provider.test.d.ts.map +1 -0
- package/dist/daemon/methods/__tests__/provider.test.js +184 -0
- package/dist/daemon/methods/__tests__/provider.test.js.map +1 -0
- package/dist/daemon/methods/__tests__/tools.test.d.ts +5 -0
- package/dist/daemon/methods/__tests__/tools.test.d.ts.map +1 -0
- package/dist/daemon/methods/__tests__/tools.test.js +295 -0
- package/dist/daemon/methods/__tests__/tools.test.js.map +1 -0
- package/dist/daemon/methods/archive.d.ts +22 -0
- package/dist/daemon/methods/archive.d.ts.map +1 -0
- package/dist/daemon/methods/archive.js +107 -0
- package/dist/daemon/methods/archive.js.map +1 -0
- package/dist/daemon/methods/graph.d.ts +26 -0
- package/dist/daemon/methods/graph.d.ts.map +1 -0
- package/dist/daemon/methods/graph.js +157 -0
- package/dist/daemon/methods/graph.js.map +1 -0
- package/dist/daemon/methods/lifecycle.d.ts +54 -0
- package/dist/daemon/methods/lifecycle.d.ts.map +1 -0
- package/dist/daemon/methods/lifecycle.js +46 -0
- package/dist/daemon/methods/lifecycle.js.map +1 -0
- package/dist/daemon/methods/location.d.ts +24 -0
- package/dist/daemon/methods/location.d.ts.map +1 -0
- package/dist/daemon/methods/location.js +72 -0
- package/dist/daemon/methods/location.js.map +1 -0
- package/dist/daemon/methods/provider.d.ts +22 -0
- package/dist/daemon/methods/provider.d.ts.map +1 -0
- package/dist/daemon/methods/provider.js +72 -0
- package/dist/daemon/methods/provider.js.map +1 -0
- package/dist/daemon/methods/tools.d.ts +23 -0
- package/dist/daemon/methods/tools.d.ts.map +1 -0
- package/dist/daemon/methods/tools.js +111 -0
- package/dist/daemon/methods/tools.js.map +1 -0
- package/dist/daemon/registry.d.ts +35 -0
- package/dist/daemon/registry.d.ts.map +1 -0
- package/dist/daemon/registry.js +189 -0
- package/dist/daemon/registry.js.map +1 -0
- package/dist/daemon/types.d.ts +101 -0
- package/dist/daemon/types.d.ts.map +1 -0
- package/dist/daemon/types.js +19 -0
- package/dist/daemon/types.js.map +1 -0
- package/dist/daemon/watcher.d.ts +62 -0
- package/dist/daemon/watcher.d.ts.map +1 -0
- package/dist/daemon/watcher.js +142 -0
- package/dist/daemon/watcher.js.map +1 -0
- package/dist/graph/EdgeTypeRegistry.d.ts +134 -0
- package/dist/graph/EdgeTypeRegistry.d.ts.map +1 -0
- package/dist/graph/EdgeTypeRegistry.js +255 -0
- package/dist/graph/EdgeTypeRegistry.js.map +1 -0
- package/dist/graph/FederatedGraph.d.ts +296 -0
- package/dist/graph/FederatedGraph.d.ts.map +1 -0
- package/dist/graph/FederatedGraph.js +406 -0
- package/dist/graph/FederatedGraph.js.map +1 -0
- package/dist/graph/GraphologyAdapter.d.ts +151 -0
- package/dist/graph/GraphologyAdapter.d.ts.map +1 -0
- package/dist/graph/GraphologyAdapter.js +209 -0
- package/dist/graph/GraphologyAdapter.js.map +1 -0
- package/dist/graph/HydratingFederatedGraph.d.ts +151 -0
- package/dist/graph/HydratingFederatedGraph.d.ts.map +1 -0
- package/dist/graph/HydratingFederatedGraph.js +327 -0
- package/dist/graph/HydratingFederatedGraph.js.map +1 -0
- package/dist/graph/__tests__/EdgeTypeRegistry.test.d.ts +2 -0
- package/dist/graph/__tests__/EdgeTypeRegistry.test.d.ts.map +1 -0
- package/dist/graph/__tests__/EdgeTypeRegistry.test.js +212 -0
- package/dist/graph/__tests__/EdgeTypeRegistry.test.js.map +1 -0
- package/dist/graph/__tests__/FederatedGraph.test.d.ts +2 -0
- package/dist/graph/__tests__/FederatedGraph.test.d.ts.map +1 -0
- package/dist/graph/__tests__/FederatedGraph.test.js +661 -0
- package/dist/graph/__tests__/FederatedGraph.test.js.map +1 -0
- package/dist/graph/__tests__/GraphologyAdapter.test.d.ts +2 -0
- package/dist/graph/__tests__/GraphologyAdapter.test.d.ts.map +1 -0
- package/dist/graph/__tests__/GraphologyAdapter.test.js +326 -0
- package/dist/graph/__tests__/GraphologyAdapter.test.js.map +1 -0
- package/dist/graph/__tests__/HydratingFederatedGraph.test.d.ts +2 -0
- package/dist/graph/__tests__/HydratingFederatedGraph.test.d.ts.map +1 -0
- package/dist/graph/__tests__/HydratingFederatedGraph.test.js +587 -0
- package/dist/graph/__tests__/HydratingFederatedGraph.test.js.map +1 -0
- package/dist/graph/__tests__/debounce.test.d.ts +5 -0
- package/dist/graph/__tests__/debounce.test.d.ts.map +1 -0
- package/dist/graph/__tests__/debounce.test.js +195 -0
- package/dist/graph/__tests__/debounce.test.js.map +1 -0
- package/dist/graph/__tests__/edge-cases.test.d.ts +8 -0
- package/dist/graph/__tests__/edge-cases.test.d.ts.map +1 -0
- package/dist/graph/__tests__/edge-cases.test.js +472 -0
- package/dist/graph/__tests__/edge-cases.test.js.map +1 -0
- package/dist/graph/__tests__/expansion.test.d.ts +2 -0
- package/dist/graph/__tests__/expansion.test.d.ts.map +1 -0
- package/dist/graph/__tests__/expansion.test.js +105 -0
- package/dist/graph/__tests__/expansion.test.js.map +1 -0
- package/dist/graph/__tests__/provider-store.test.d.ts +5 -0
- package/dist/graph/__tests__/provider-store.test.d.ts.map +1 -0
- package/dist/graph/__tests__/provider-store.test.js +791 -0
- package/dist/graph/__tests__/provider-store.test.js.map +1 -0
- package/dist/graph/__tests__/query.test.d.ts +5 -0
- package/dist/graph/__tests__/query.test.d.ts.map +1 -0
- package/dist/graph/__tests__/query.test.js +774 -0
- package/dist/graph/__tests__/query.test.js.map +1 -0
- package/dist/graph/__tests__/store.test.d.ts +5 -0
- package/dist/graph/__tests__/store.test.d.ts.map +1 -0
- package/dist/graph/__tests__/store.test.js +489 -0
- package/dist/graph/__tests__/store.test.js.map +1 -0
- package/dist/graph/__tests__/sync.test.d.ts +5 -0
- package/dist/graph/__tests__/sync.test.d.ts.map +1 -0
- package/dist/graph/__tests__/sync.test.js +129 -0
- package/dist/graph/__tests__/sync.test.js.map +1 -0
- package/dist/graph/__tests__/validation.test.d.ts +2 -0
- package/dist/graph/__tests__/validation.test.d.ts.map +1 -0
- package/dist/graph/__tests__/validation.test.js +521 -0
- package/dist/graph/__tests__/validation.test.js.map +1 -0
- package/dist/graph/coordination.d.ts +190 -0
- package/dist/graph/coordination.d.ts.map +1 -0
- package/dist/graph/coordination.js +180 -0
- package/dist/graph/coordination.js.map +1 -0
- package/dist/graph/debounce.d.ts +47 -0
- package/dist/graph/debounce.d.ts.map +1 -0
- package/dist/graph/debounce.js +95 -0
- package/dist/graph/debounce.js.map +1 -0
- package/dist/graph/expansion.d.ts +64 -0
- package/dist/graph/expansion.d.ts.map +1 -0
- package/dist/graph/expansion.js +205 -0
- package/dist/graph/expansion.js.map +1 -0
- package/dist/graph/history.d.ts +186 -0
- package/dist/graph/history.d.ts.map +1 -0
- package/dist/graph/history.js +155 -0
- package/dist/graph/history.js.map +1 -0
- package/dist/graph/index.d.ts +35 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +22 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/provider-store.d.ts +211 -0
- package/dist/graph/provider-store.d.ts.map +1 -0
- package/dist/graph/provider-store.js +594 -0
- package/dist/graph/provider-store.js.map +1 -0
- package/dist/graph/query.d.ts +90 -0
- package/dist/graph/query.d.ts.map +1 -0
- package/dist/graph/query.js +463 -0
- package/dist/graph/query.js.map +1 -0
- package/dist/graph/store.d.ts +71 -0
- package/dist/graph/store.d.ts.map +1 -0
- package/dist/graph/store.js +531 -0
- package/dist/graph/store.js.map +1 -0
- package/dist/graph/sync.d.ts +48 -0
- package/dist/graph/sync.d.ts.map +1 -0
- package/dist/graph/sync.js +60 -0
- package/dist/graph/sync.js.map +1 -0
- package/dist/graph/types.d.ts +291 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +19 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/graph/validation.d.ts +26 -0
- package/dist/graph/validation.d.ts.map +1 -0
- package/dist/graph/validation.js +338 -0
- package/dist/graph/validation.js.map +1 -0
- package/dist/index.d.ts +25 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -25
- package/dist/index.js.map +1 -1
- package/dist/materialization/archiver.d.ts +12 -0
- package/dist/materialization/archiver.d.ts.map +1 -0
- package/dist/materialization/archiver.js +273 -0
- package/dist/materialization/archiver.js.map +1 -0
- package/dist/materialization/git-archive-store.d.ts +17 -0
- package/dist/materialization/git-archive-store.d.ts.map +1 -0
- package/dist/materialization/git-archive-store.js +509 -0
- package/dist/materialization/git-archive-store.js.map +1 -0
- package/dist/materialization/git-remote-store.d.ts +22 -0
- package/dist/materialization/git-remote-store.d.ts.map +1 -0
- package/dist/materialization/git-remote-store.js +448 -0
- package/dist/materialization/git-remote-store.js.map +1 -0
- package/dist/materialization/graph-id.d.ts +53 -0
- package/dist/materialization/graph-id.d.ts.map +1 -0
- package/dist/materialization/graph-id.js +163 -0
- package/dist/materialization/graph-id.js.map +1 -0
- package/dist/materialization/http-remote-store.d.ts +12 -0
- package/dist/materialization/http-remote-store.d.ts.map +1 -0
- package/dist/materialization/http-remote-store.js +143 -0
- package/dist/materialization/http-remote-store.js.map +1 -0
- package/dist/materialization/index.d.ts +15 -0
- package/dist/materialization/index.d.ts.map +1 -0
- package/dist/materialization/index.js +17 -0
- package/dist/materialization/index.js.map +1 -0
- package/dist/materialization/remote-store-factory.d.ts +17 -0
- package/dist/materialization/remote-store-factory.d.ts.map +1 -0
- package/dist/materialization/remote-store-factory.js +46 -0
- package/dist/materialization/remote-store-factory.js.map +1 -0
- package/dist/materialization/snapshot.d.ts +34 -0
- package/dist/materialization/snapshot.d.ts.map +1 -0
- package/dist/materialization/snapshot.js +177 -0
- package/dist/materialization/snapshot.js.map +1 -0
- package/dist/materialization/types.d.ts +300 -0
- package/dist/materialization/types.d.ts.map +1 -0
- package/dist/materialization/types.js +17 -0
- package/dist/materialization/types.js.map +1 -0
- package/dist/providers/__tests__/beads.test.d.ts +5 -0
- package/dist/providers/__tests__/beads.test.d.ts.map +1 -0
- package/dist/providers/__tests__/beads.test.js +591 -0
- package/dist/providers/__tests__/beads.test.js.map +1 -0
- package/dist/providers/__tests__/claude-tasks.test.d.ts +5 -0
- package/dist/providers/__tests__/claude-tasks.test.d.ts.map +1 -0
- package/dist/providers/__tests__/claude-tasks.test.js +392 -0
- package/dist/providers/__tests__/claude-tasks.test.js.map +1 -0
- package/dist/providers/__tests__/from-config.test.d.ts +5 -0
- package/dist/providers/__tests__/from-config.test.d.ts.map +1 -0
- package/dist/providers/__tests__/from-config.test.js +152 -0
- package/dist/providers/__tests__/from-config.test.js.map +1 -0
- package/dist/providers/__tests__/materialization.test.d.ts +5 -0
- package/dist/providers/__tests__/materialization.test.d.ts.map +1 -0
- package/dist/providers/__tests__/materialization.test.js +407 -0
- package/dist/providers/__tests__/materialization.test.js.map +1 -0
- package/dist/providers/__tests__/native.test.d.ts +5 -0
- package/dist/providers/__tests__/native.test.d.ts.map +1 -0
- package/dist/providers/__tests__/native.test.js +566 -0
- package/dist/providers/__tests__/native.test.js.map +1 -0
- package/dist/providers/__tests__/registry.test.d.ts +5 -0
- package/dist/providers/__tests__/registry.test.d.ts.map +1 -0
- package/dist/providers/__tests__/registry.test.js +183 -0
- package/dist/providers/__tests__/registry.test.js.map +1 -0
- package/dist/providers/beads.d.ts +46 -0
- package/dist/providers/beads.d.ts.map +1 -0
- package/dist/providers/beads.js +865 -0
- package/dist/providers/beads.js.map +1 -0
- package/dist/providers/claude-tasks.d.ts +56 -0
- package/dist/providers/claude-tasks.d.ts.map +1 -0
- package/dist/providers/claude-tasks.js +282 -0
- package/dist/providers/claude-tasks.js.map +1 -0
- package/dist/providers/entire.d.ts +88 -0
- package/dist/providers/entire.d.ts.map +1 -0
- package/dist/providers/entire.js +409 -0
- package/dist/providers/entire.js.map +1 -0
- package/dist/providers/from-config.d.ts +47 -0
- package/dist/providers/from-config.d.ts.map +1 -0
- package/dist/providers/from-config.js +150 -0
- package/dist/providers/from-config.js.map +1 -0
- package/dist/providers/index.d.ts +26 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +29 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/location.d.ts +44 -0
- package/dist/providers/location.d.ts.map +1 -0
- package/dist/providers/location.js +157 -0
- package/dist/providers/location.js.map +1 -0
- package/dist/providers/materialization.d.ts +46 -0
- package/dist/providers/materialization.d.ts.map +1 -0
- package/dist/providers/materialization.js +237 -0
- package/dist/providers/materialization.js.map +1 -0
- package/dist/providers/native.d.ts +32 -0
- package/dist/providers/native.d.ts.map +1 -0
- package/dist/providers/native.js +552 -0
- package/dist/providers/native.js.map +1 -0
- package/dist/providers/registry.d.ts +11 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +97 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/sudocode.d.ts +49 -0
- package/dist/providers/sudocode.d.ts.map +1 -0
- package/dist/providers/sudocode.js +945 -0
- package/dist/providers/sudocode.js.map +1 -0
- package/dist/providers/sync.d.ts +299 -0
- package/dist/providers/sync.d.ts.map +1 -0
- package/dist/providers/sync.js +93 -0
- package/dist/providers/sync.js.map +1 -0
- package/dist/providers/traits/RelationshipQueryable.d.ts +129 -0
- package/dist/providers/traits/RelationshipQueryable.d.ts.map +1 -0
- package/dist/providers/traits/RelationshipQueryable.js +68 -0
- package/dist/providers/traits/RelationshipQueryable.js.map +1 -0
- package/dist/providers/traits/TaskManageable.d.ts +157 -0
- package/dist/providers/traits/TaskManageable.d.ts.map +1 -0
- package/dist/providers/traits/TaskManageable.js +37 -0
- package/dist/providers/traits/TaskManageable.js.map +1 -0
- package/dist/providers/traits/Watchable.d.ts +216 -0
- package/dist/providers/traits/Watchable.d.ts.map +1 -0
- package/dist/providers/traits/Watchable.js +37 -0
- package/dist/providers/traits/Watchable.js.map +1 -0
- package/dist/providers/traits/__tests__/RelationshipQueryable.test.d.ts +2 -0
- package/dist/providers/traits/__tests__/RelationshipQueryable.test.d.ts.map +1 -0
- package/dist/providers/traits/__tests__/RelationshipQueryable.test.js +169 -0
- package/dist/providers/traits/__tests__/RelationshipQueryable.test.js.map +1 -0
- package/dist/providers/traits/__tests__/TaskManageable.test.d.ts +2 -0
- package/dist/providers/traits/__tests__/TaskManageable.test.d.ts.map +1 -0
- package/dist/providers/traits/__tests__/TaskManageable.test.js +172 -0
- package/dist/providers/traits/__tests__/TaskManageable.test.js.map +1 -0
- package/dist/providers/traits/index.d.ts +13 -0
- package/dist/providers/traits/index.d.ts.map +1 -0
- package/dist/providers/traits/index.js +10 -0
- package/dist/providers/traits/index.js.map +1 -0
- package/dist/providers/types.d.ts +284 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +30 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/schema/__tests__/validation.test.d.ts +2 -0
- package/dist/schema/__tests__/validation.test.d.ts.map +1 -0
- package/dist/schema/__tests__/validation.test.js +241 -0
- package/dist/schema/__tests__/validation.test.js.map +1 -0
- package/dist/schema/base.d.ts +68 -0
- package/dist/schema/base.d.ts.map +1 -0
- package/dist/schema/base.js +5 -0
- package/dist/schema/base.js.map +1 -0
- package/dist/schema/edges.d.ts +49 -0
- package/dist/schema/edges.d.ts.map +1 -0
- package/dist/schema/edges.js +9 -0
- package/dist/schema/edges.js.map +1 -0
- package/dist/schema/index.d.ts +11 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +8 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/nodes.d.ts +97 -0
- package/dist/schema/nodes.d.ts.map +1 -0
- package/dist/schema/nodes.js +5 -0
- package/dist/schema/nodes.js.map +1 -0
- package/dist/schema/storage.d.ts +107 -0
- package/dist/schema/storage.d.ts.map +1 -0
- package/dist/schema/storage.js +10 -0
- package/dist/schema/storage.js.map +1 -0
- package/dist/schema/validation.d.ts +61 -0
- package/dist/schema/validation.d.ts.map +1 -0
- package/dist/schema/validation.js +170 -0
- package/dist/schema/validation.js.map +1 -0
- package/dist/storage/__tests__/atomic-write.test.d.ts +5 -0
- package/dist/storage/__tests__/atomic-write.test.d.ts.map +1 -0
- package/dist/storage/__tests__/atomic-write.test.js +170 -0
- package/dist/storage/__tests__/atomic-write.test.js.map +1 -0
- package/dist/storage/__tests__/file-lock.test.d.ts +2 -0
- package/dist/storage/__tests__/file-lock.test.d.ts.map +1 -0
- package/dist/storage/__tests__/file-lock.test.js +89 -0
- package/dist/storage/__tests__/file-lock.test.js.map +1 -0
- package/dist/storage/__tests__/jsonl.test.d.ts +2 -0
- package/dist/storage/__tests__/jsonl.test.d.ts.map +1 -0
- package/dist/storage/__tests__/jsonl.test.js +228 -0
- package/dist/storage/__tests__/jsonl.test.js.map +1 -0
- package/dist/storage/__tests__/locked-writer.test.d.ts +2 -0
- package/dist/storage/__tests__/locked-writer.test.d.ts.map +1 -0
- package/dist/storage/__tests__/locked-writer.test.js +109 -0
- package/dist/storage/__tests__/locked-writer.test.js.map +1 -0
- package/dist/storage/__tests__/sqlite.test.d.ts +2 -0
- package/dist/storage/__tests__/sqlite.test.d.ts.map +1 -0
- package/dist/storage/__tests__/sqlite.test.js +470 -0
- package/dist/storage/__tests__/sqlite.test.js.map +1 -0
- package/dist/storage/atomic-write.d.ts +38 -0
- package/dist/storage/atomic-write.d.ts.map +1 -0
- package/dist/storage/atomic-write.js +83 -0
- package/dist/storage/atomic-write.js.map +1 -0
- package/dist/storage/file-lock.d.ts +66 -0
- package/dist/storage/file-lock.d.ts.map +1 -0
- package/dist/storage/file-lock.js +176 -0
- package/dist/storage/file-lock.js.map +1 -0
- package/dist/storage/index.d.ts +11 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +13 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/interface.d.ts +219 -0
- package/dist/storage/interface.d.ts.map +1 -0
- package/dist/storage/interface.js +22 -0
- package/dist/storage/interface.js.map +1 -0
- package/dist/storage/jsonl.d.ts +106 -0
- package/dist/storage/jsonl.d.ts.map +1 -0
- package/dist/storage/jsonl.js +218 -0
- package/dist/storage/jsonl.js.map +1 -0
- package/dist/storage/locked-writer.d.ts +67 -0
- package/dist/storage/locked-writer.d.ts.map +1 -0
- package/dist/storage/locked-writer.js +105 -0
- package/dist/storage/locked-writer.js.map +1 -0
- package/dist/storage/sqlite-schema.d.ts +48 -0
- package/dist/storage/sqlite-schema.d.ts.map +1 -0
- package/dist/storage/sqlite-schema.js +169 -0
- package/dist/storage/sqlite-schema.js.map +1 -0
- package/dist/storage/sqlite.d.ts +73 -0
- package/dist/storage/sqlite.d.ts.map +1 -0
- package/dist/storage/sqlite.js +698 -0
- package/dist/storage/sqlite.js.map +1 -0
- package/dist/tools/__tests__/annotate.test.d.ts +5 -0
- package/dist/tools/__tests__/annotate.test.d.ts.map +1 -0
- package/dist/tools/__tests__/annotate.test.js +314 -0
- package/dist/tools/__tests__/annotate.test.js.map +1 -0
- package/dist/tools/__tests__/link.test.d.ts +5 -0
- package/dist/tools/__tests__/link.test.d.ts.map +1 -0
- package/dist/tools/__tests__/link.test.js +245 -0
- package/dist/tools/__tests__/link.test.js.map +1 -0
- package/dist/tools/__tests__/query.test.d.ts +5 -0
- package/dist/tools/__tests__/query.test.d.ts.map +1 -0
- package/dist/tools/__tests__/query.test.js +288 -0
- package/dist/tools/__tests__/query.test.js.map +1 -0
- package/dist/tools/__tests__/task.test.d.ts +5 -0
- package/dist/tools/__tests__/task.test.d.ts.map +1 -0
- package/dist/tools/__tests__/task.test.js +178 -0
- package/dist/tools/__tests__/task.test.js.map +1 -0
- package/dist/tools/annotate.d.ts +17 -0
- package/dist/tools/annotate.d.ts.map +1 -0
- package/dist/tools/annotate.js +218 -0
- package/dist/tools/annotate.js.map +1 -0
- package/dist/tools/index.d.ts +14 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +14 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/link.d.ts +17 -0
- package/dist/tools/link.d.ts.map +1 -0
- package/dist/tools/link.js +127 -0
- package/dist/tools/link.js.map +1 -0
- package/dist/tools/query.d.ts +17 -0
- package/dist/tools/query.d.ts.map +1 -0
- package/dist/tools/query.js +342 -0
- package/dist/tools/query.js.map +1 -0
- package/dist/tools/task.d.ts +20 -0
- package/dist/tools/task.d.ts.map +1 -0
- package/dist/tools/task.js +161 -0
- package/dist/tools/task.js.map +1 -0
- package/dist/tools/types.d.ts +334 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +19 -0
- package/dist/tools/types.js.map +1 -0
- package/package.json +40 -5
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSONL Persister for OpenTasks
|
|
3
|
+
*
|
|
4
|
+
* Git-friendly JSONL storage as source of truth.
|
|
5
|
+
* Each line is a JSON object (node or edge).
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'node:fs';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import { atomicWrite, appendToFile, fileExists, readFileOrEmpty } from './atomic-write.js';
|
|
10
|
+
/**
|
|
11
|
+
* Determine if a parsed JSON object is an edge
|
|
12
|
+
*
|
|
13
|
+
* Edges have from_id and to_id fields, or id starting with 'x-'
|
|
14
|
+
*/
|
|
15
|
+
function isEdge(obj) {
|
|
16
|
+
return (('from_id' in obj && 'to_id' in obj) || (typeof obj.id === 'string' && obj.id.startsWith('x-')));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* JSONL Persister
|
|
20
|
+
*
|
|
21
|
+
* Handles reading/writing graph data to JSONL files.
|
|
22
|
+
* Source of truth for OpenTasks data.
|
|
23
|
+
*/
|
|
24
|
+
export class JSONLPersister {
|
|
25
|
+
config;
|
|
26
|
+
watcher = null;
|
|
27
|
+
constructor(config) {
|
|
28
|
+
this.config = {
|
|
29
|
+
path: config.path,
|
|
30
|
+
tombstonesPath: config.tombstonesPath || config.path.replace('.jsonl', '.tombstones.jsonl'),
|
|
31
|
+
atomicWrite: config.atomicWrite ?? true,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get the file path
|
|
36
|
+
*/
|
|
37
|
+
get filePath() {
|
|
38
|
+
return this.config.path;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Check if the JSONL file exists
|
|
42
|
+
*/
|
|
43
|
+
async exists() {
|
|
44
|
+
return fileExists(this.config.path);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Load the entire graph from JSONL
|
|
48
|
+
*
|
|
49
|
+
* Parses each line as JSON and separates nodes from edges.
|
|
50
|
+
* Invalid lines are skipped with a warning.
|
|
51
|
+
*
|
|
52
|
+
* @returns Object with nodes and edges arrays
|
|
53
|
+
*/
|
|
54
|
+
async load() {
|
|
55
|
+
const content = await readFileOrEmpty(this.config.path);
|
|
56
|
+
if (!content.trim()) {
|
|
57
|
+
return { nodes: [], edges: [] };
|
|
58
|
+
}
|
|
59
|
+
const nodes = [];
|
|
60
|
+
const edges = [];
|
|
61
|
+
const lines = content.split('\n');
|
|
62
|
+
for (let i = 0; i < lines.length; i++) {
|
|
63
|
+
const line = lines[i].trim();
|
|
64
|
+
if (!line)
|
|
65
|
+
continue;
|
|
66
|
+
try {
|
|
67
|
+
const obj = JSON.parse(line);
|
|
68
|
+
if (isEdge(obj)) {
|
|
69
|
+
edges.push(obj);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
nodes.push(obj);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
console.warn(`Invalid JSON at line ${i + 1}: ${line.slice(0, 50)}...`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return { nodes, edges };
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Save the entire graph to JSONL
|
|
83
|
+
*
|
|
84
|
+
* Overwrites the file with all nodes and edges.
|
|
85
|
+
* Uses atomic write by default (temp file + rename).
|
|
86
|
+
*
|
|
87
|
+
* @param nodes - All nodes to save
|
|
88
|
+
* @param edges - All edges to save
|
|
89
|
+
*/
|
|
90
|
+
async save(nodes, edges) {
|
|
91
|
+
const lines = [];
|
|
92
|
+
// Nodes first
|
|
93
|
+
for (const node of nodes) {
|
|
94
|
+
lines.push(JSON.stringify(node));
|
|
95
|
+
}
|
|
96
|
+
// Then edges
|
|
97
|
+
for (const edge of edges) {
|
|
98
|
+
lines.push(JSON.stringify(edge));
|
|
99
|
+
}
|
|
100
|
+
const content = lines.join('\n') + (lines.length > 0 ? '\n' : '');
|
|
101
|
+
if (this.config.atomicWrite) {
|
|
102
|
+
await atomicWrite(this.config.path, content);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
const dir = path.dirname(this.config.path);
|
|
106
|
+
await fs.promises.mkdir(dir, { recursive: true });
|
|
107
|
+
await fs.promises.writeFile(this.config.path, content, 'utf-8');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Append a single entry to the JSONL file
|
|
112
|
+
*
|
|
113
|
+
* Useful for incremental writes without rewriting the entire file.
|
|
114
|
+
* Note: This can lead to duplicate entries; use save() for clean state.
|
|
115
|
+
*
|
|
116
|
+
* @param entry - Node or edge to append
|
|
117
|
+
*/
|
|
118
|
+
async append(entry) {
|
|
119
|
+
const line = JSON.stringify(entry) + '\n';
|
|
120
|
+
await appendToFile(this.config.path, line);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Append multiple entries to the JSONL file
|
|
124
|
+
*
|
|
125
|
+
* @param entries - Nodes or edges to append
|
|
126
|
+
*/
|
|
127
|
+
async appendMany(entries) {
|
|
128
|
+
if (entries.length === 0)
|
|
129
|
+
return;
|
|
130
|
+
const lines = entries.map((e) => JSON.stringify(e)).join('\n') + '\n';
|
|
131
|
+
await appendToFile(this.config.path, lines);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Watch the JSONL file for external changes
|
|
135
|
+
*
|
|
136
|
+
* Calls the callback when the file is modified.
|
|
137
|
+
* Uses debouncing to avoid multiple calls for rapid changes.
|
|
138
|
+
*
|
|
139
|
+
* @param callback - Function to call on file change
|
|
140
|
+
* @returns Unsubscribe function
|
|
141
|
+
*/
|
|
142
|
+
watch(callback) {
|
|
143
|
+
if (this.watcher) {
|
|
144
|
+
this.watcher.close();
|
|
145
|
+
}
|
|
146
|
+
let debounceTimer = null;
|
|
147
|
+
const debouncedCallback = () => {
|
|
148
|
+
if (debounceTimer) {
|
|
149
|
+
clearTimeout(debounceTimer);
|
|
150
|
+
}
|
|
151
|
+
debounceTimer = setTimeout(() => {
|
|
152
|
+
callback();
|
|
153
|
+
debounceTimer = null;
|
|
154
|
+
}, 100);
|
|
155
|
+
};
|
|
156
|
+
try {
|
|
157
|
+
this.watcher = fs.watch(this.config.path, (eventType) => {
|
|
158
|
+
if (eventType === 'change') {
|
|
159
|
+
debouncedCallback();
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
this.watcher.on('error', (error) => {
|
|
163
|
+
console.warn('File watcher error:', error);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
// File might not exist yet - that's OK
|
|
168
|
+
console.warn('Could not watch file:', this.config.path);
|
|
169
|
+
}
|
|
170
|
+
return () => {
|
|
171
|
+
if (debounceTimer) {
|
|
172
|
+
clearTimeout(debounceTimer);
|
|
173
|
+
}
|
|
174
|
+
if (this.watcher) {
|
|
175
|
+
this.watcher.close();
|
|
176
|
+
this.watcher = null;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Stop watching the file
|
|
182
|
+
*/
|
|
183
|
+
stopWatching() {
|
|
184
|
+
if (this.watcher) {
|
|
185
|
+
this.watcher.close();
|
|
186
|
+
this.watcher = null;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Delete the JSONL file
|
|
191
|
+
*
|
|
192
|
+
* Use with caution - this removes all data.
|
|
193
|
+
*/
|
|
194
|
+
async delete() {
|
|
195
|
+
try {
|
|
196
|
+
await fs.promises.unlink(this.config.path);
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
if (error.code !== 'ENOENT') {
|
|
200
|
+
throw error;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Create a JSONL persister with default configuration
|
|
207
|
+
*
|
|
208
|
+
* @param basePath - Base directory (e.g., ".opentasks")
|
|
209
|
+
* @returns Configured JSONLPersister
|
|
210
|
+
*/
|
|
211
|
+
export function createJSONLPersister(basePath) {
|
|
212
|
+
return new JSONLPersister({
|
|
213
|
+
path: path.join(basePath, 'graph.jsonl'),
|
|
214
|
+
tombstonesPath: path.join(basePath, 'tombstones.jsonl'),
|
|
215
|
+
atomicWrite: true,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=jsonl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonl.js","sourceRoot":"","sources":["../../src/storage/jsonl.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Locked JSONL Writer for OpenTasks (Phase 2)
|
|
3
|
+
*
|
|
4
|
+
* Wraps JSONL append operations with advisory file locking
|
|
5
|
+
* for safe concurrent access across multiple processes.
|
|
6
|
+
*/
|
|
7
|
+
import type { StoredNode, StoredEdge } from '../schema/storage.js';
|
|
8
|
+
import { JSONLPersister } from './jsonl.js';
|
|
9
|
+
/**
|
|
10
|
+
* Configuration for the locked writer
|
|
11
|
+
*/
|
|
12
|
+
export interface LockedWriterConfig {
|
|
13
|
+
/** Path to the .opentasks directory */
|
|
14
|
+
basePath: string;
|
|
15
|
+
/** Lock acquisition timeout (ms) */
|
|
16
|
+
lockTimeout?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Locked JSONL writer
|
|
20
|
+
*
|
|
21
|
+
* All write operations acquire an advisory file lock before
|
|
22
|
+
* appending to graph.jsonl. Reads do NOT require the lock
|
|
23
|
+
* (SQLite WAL handles concurrent reads).
|
|
24
|
+
*/
|
|
25
|
+
export declare class LockedJsonlWriter {
|
|
26
|
+
private readonly persister;
|
|
27
|
+
private readonly lockPath;
|
|
28
|
+
private readonly lockTimeout;
|
|
29
|
+
constructor(config: LockedWriterConfig);
|
|
30
|
+
/**
|
|
31
|
+
* Append a single entry while holding the write lock
|
|
32
|
+
*/
|
|
33
|
+
appendLocked(entry: StoredNode | StoredEdge): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Append multiple entries while holding the write lock
|
|
36
|
+
*/
|
|
37
|
+
appendManyLocked(entries: Array<StoredNode | StoredEdge>): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Save (overwrite) the entire file while holding the write lock
|
|
40
|
+
*/
|
|
41
|
+
saveLocked(nodes: StoredNode[], edges: StoredEdge[]): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Load from JSONL (no lock needed — reads are safe)
|
|
44
|
+
*/
|
|
45
|
+
load(): Promise<import("./jsonl.js").LoadResult>;
|
|
46
|
+
/**
|
|
47
|
+
* Get the underlying persister for non-locked operations
|
|
48
|
+
*/
|
|
49
|
+
get underlying(): JSONLPersister;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Deduplicate JSONL entries by keeping the latest updated_at per ID
|
|
53
|
+
*
|
|
54
|
+
* Used during cache rebuild to resolve append-only duplicates.
|
|
55
|
+
*
|
|
56
|
+
* @param nodes - All node entries (may include duplicates)
|
|
57
|
+
* @returns Deduplicated nodes
|
|
58
|
+
*/
|
|
59
|
+
export declare function deduplicateNodes(nodes: StoredNode[]): StoredNode[];
|
|
60
|
+
/**
|
|
61
|
+
* Deduplicate edge entries by keeping the latest per ID
|
|
62
|
+
*
|
|
63
|
+
* @param edges - All edge entries (may include duplicates)
|
|
64
|
+
* @returns Deduplicated edges
|
|
65
|
+
*/
|
|
66
|
+
export declare function deduplicateEdges(edges: StoredEdge[]): StoredEdge[];
|
|
67
|
+
//# sourceMappingURL=locked-writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locked-writer.d.ts","sourceRoot":"","sources":["../../src/storage/locked-writer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG5C;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;GAMG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,MAAM,EAAE,kBAAkB;IAQtC;;OAEG;IACG,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAUjE;;OAEG;IACG,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAY9E;;OAEG;IACG,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAUzE;;OAEG;IACG,IAAI;IAIV;;OAEG;IACH,IAAI,UAAU,IAAI,cAAc,CAE/B;CACF;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAWlE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAclE"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Locked JSONL Writer for OpenTasks (Phase 2)
|
|
3
|
+
*
|
|
4
|
+
* Wraps JSONL append operations with advisory file locking
|
|
5
|
+
* for safe concurrent access across multiple processes.
|
|
6
|
+
*/
|
|
7
|
+
import * as path from 'node:path';
|
|
8
|
+
import { JSONLPersister } from './jsonl.js';
|
|
9
|
+
import { withFileLock } from './file-lock.js';
|
|
10
|
+
/**
|
|
11
|
+
* Locked JSONL writer
|
|
12
|
+
*
|
|
13
|
+
* All write operations acquire an advisory file lock before
|
|
14
|
+
* appending to graph.jsonl. Reads do NOT require the lock
|
|
15
|
+
* (SQLite WAL handles concurrent reads).
|
|
16
|
+
*/
|
|
17
|
+
export class LockedJsonlWriter {
|
|
18
|
+
persister;
|
|
19
|
+
lockPath;
|
|
20
|
+
lockTimeout;
|
|
21
|
+
constructor(config) {
|
|
22
|
+
this.persister = new JSONLPersister({
|
|
23
|
+
path: path.join(config.basePath, 'graph.jsonl'),
|
|
24
|
+
});
|
|
25
|
+
this.lockPath = path.join(config.basePath, 'write.lock');
|
|
26
|
+
this.lockTimeout = config.lockTimeout ?? 5000;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Append a single entry while holding the write lock
|
|
30
|
+
*/
|
|
31
|
+
async appendLocked(entry) {
|
|
32
|
+
await withFileLock(this.lockPath, async () => {
|
|
33
|
+
await this.persister.append(entry);
|
|
34
|
+
}, this.lockTimeout);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Append multiple entries while holding the write lock
|
|
38
|
+
*/
|
|
39
|
+
async appendManyLocked(entries) {
|
|
40
|
+
if (entries.length === 0)
|
|
41
|
+
return;
|
|
42
|
+
await withFileLock(this.lockPath, async () => {
|
|
43
|
+
await this.persister.appendMany(entries);
|
|
44
|
+
}, this.lockTimeout);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Save (overwrite) the entire file while holding the write lock
|
|
48
|
+
*/
|
|
49
|
+
async saveLocked(nodes, edges) {
|
|
50
|
+
await withFileLock(this.lockPath, async () => {
|
|
51
|
+
await this.persister.save(nodes, edges);
|
|
52
|
+
}, this.lockTimeout);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Load from JSONL (no lock needed — reads are safe)
|
|
56
|
+
*/
|
|
57
|
+
async load() {
|
|
58
|
+
return this.persister.load();
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get the underlying persister for non-locked operations
|
|
62
|
+
*/
|
|
63
|
+
get underlying() {
|
|
64
|
+
return this.persister;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Deduplicate JSONL entries by keeping the latest updated_at per ID
|
|
69
|
+
*
|
|
70
|
+
* Used during cache rebuild to resolve append-only duplicates.
|
|
71
|
+
*
|
|
72
|
+
* @param nodes - All node entries (may include duplicates)
|
|
73
|
+
* @returns Deduplicated nodes
|
|
74
|
+
*/
|
|
75
|
+
export function deduplicateNodes(nodes) {
|
|
76
|
+
const map = new Map();
|
|
77
|
+
for (const node of nodes) {
|
|
78
|
+
const existing = map.get(node.id);
|
|
79
|
+
if (!existing || node.updated_at > existing.updated_at) {
|
|
80
|
+
map.set(node.id, node);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return Array.from(map.values());
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Deduplicate edge entries by keeping the latest per ID
|
|
87
|
+
*
|
|
88
|
+
* @param edges - All edge entries (may include duplicates)
|
|
89
|
+
* @returns Deduplicated edges
|
|
90
|
+
*/
|
|
91
|
+
export function deduplicateEdges(edges) {
|
|
92
|
+
const map = new Map();
|
|
93
|
+
for (const edge of edges) {
|
|
94
|
+
const existing = map.get(edge.id);
|
|
95
|
+
if (!existing) {
|
|
96
|
+
map.set(edge.id, edge);
|
|
97
|
+
}
|
|
98
|
+
else if (edge.created_at > existing.created_at) {
|
|
99
|
+
// Both have created_at (required field) — keep the newer one
|
|
100
|
+
map.set(edge.id, edge);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return Array.from(map.values());
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=locked-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locked-writer.js","sourceRoot":"","sources":["../../src/storage/locked-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite schema definitions for OpenTasks
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Create nodes table
|
|
6
|
+
*/
|
|
7
|
+
export declare const CREATE_NODES_TABLE = "\nCREATE TABLE IF NOT EXISTS nodes (\n id TEXT PRIMARY KEY,\n uuid TEXT UNIQUE NOT NULL,\n type TEXT NOT NULL,\n title TEXT NOT NULL,\n content TEXT,\n content_hash TEXT,\n status TEXT,\n priority INTEGER,\n assignee TEXT,\n parent_id TEXT,\n source TEXT,\n archived INTEGER DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n\n -- Feedback fields\n target_id TEXT,\n feedback_type TEXT,\n thread_id TEXT,\n reply_to_id TEXT,\n resolved INTEGER,\n dismissed INTEGER,\n\n -- External fields\n uri TEXT,\n materialized INTEGER,\n cached_at TEXT,\n stale INTEGER,\n external_status TEXT,\n\n -- Coordination\n claimed_by TEXT,\n claimed_at TEXT,\n lock_until TEXT,\n\n -- Context\n location TEXT,\n branch TEXT,\n\n FOREIGN KEY (parent_id) REFERENCES nodes(id)\n)\n";
|
|
8
|
+
/**
|
|
9
|
+
* Create tags join table
|
|
10
|
+
*/
|
|
11
|
+
export declare const CREATE_NODE_TAGS_TABLE = "\nCREATE TABLE IF NOT EXISTS node_tags (\n node_id TEXT NOT NULL,\n tag TEXT NOT NULL,\n PRIMARY KEY (node_id, tag),\n FOREIGN KEY (node_id) REFERENCES nodes(id) ON DELETE CASCADE\n)\n";
|
|
12
|
+
/**
|
|
13
|
+
* Create edges table
|
|
14
|
+
*/
|
|
15
|
+
export declare const CREATE_EDGES_TABLE = "\nCREATE TABLE IF NOT EXISTS edges (\n id TEXT PRIMARY KEY,\n uuid TEXT UNIQUE NOT NULL,\n from_id TEXT NOT NULL,\n to_id TEXT NOT NULL,\n type TEXT NOT NULL,\n created_at TEXT NOT NULL,\n created_by TEXT,\n source TEXT,\n metadata TEXT,\n cached_at TEXT\n)\n";
|
|
16
|
+
/**
|
|
17
|
+
* Create dirty tracking table
|
|
18
|
+
*/
|
|
19
|
+
export declare const CREATE_DIRTY_NODES_TABLE = "\nCREATE TABLE IF NOT EXISTS dirty_nodes (\n node_id TEXT PRIMARY KEY,\n marked_at TEXT NOT NULL\n)\n";
|
|
20
|
+
/**
|
|
21
|
+
* Create export hashes table
|
|
22
|
+
*/
|
|
23
|
+
export declare const CREATE_EXPORT_HASHES_TABLE = "\nCREATE TABLE IF NOT EXISTS export_hashes (\n node_id TEXT PRIMARY KEY,\n content_hash TEXT NOT NULL\n)\n";
|
|
24
|
+
/**
|
|
25
|
+
* Create indexes
|
|
26
|
+
*/
|
|
27
|
+
export declare const CREATE_INDEXES: string[];
|
|
28
|
+
/**
|
|
29
|
+
* Create ready_tasks view
|
|
30
|
+
* Shows tasks that are open, not archived, and have no open blockers
|
|
31
|
+
*/
|
|
32
|
+
export declare const CREATE_READY_VIEW = "\nCREATE VIEW IF NOT EXISTS ready_tasks AS\nSELECT n.* FROM nodes n\nWHERE n.type = 'task'\n AND n.status = 'open'\n AND n.archived = 0\n AND NOT EXISTS (\n SELECT 1 FROM edges e\n JOIN nodes blocker ON e.from_id = blocker.id\n WHERE e.to_id = n.id\n AND e.type = 'blocks'\n AND blocker.status != 'closed'\n AND blocker.archived = 0\n )\n";
|
|
33
|
+
/**
|
|
34
|
+
* Migration statements for existing databases
|
|
35
|
+
* These are idempotent (safe to run multiple times)
|
|
36
|
+
*/
|
|
37
|
+
export declare const MIGRATIONS: string[];
|
|
38
|
+
/**
|
|
39
|
+
* Apply migrations safely (ignores "duplicate column" errors)
|
|
40
|
+
*/
|
|
41
|
+
export declare function applyMigrations(db: {
|
|
42
|
+
exec: (sql: string) => void;
|
|
43
|
+
}): void;
|
|
44
|
+
/**
|
|
45
|
+
* All schema creation statements in order
|
|
46
|
+
*/
|
|
47
|
+
export declare const ALL_SCHEMA: string[];
|
|
48
|
+
//# sourceMappingURL=sqlite-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-schema.d.ts","sourceRoot":"","sources":["../../src/storage/sqlite-schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,eAAO,MAAM,kBAAkB,mzBA2C9B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,sBAAsB,iMAOlC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,kRAa9B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,wBAAwB,4GAKpC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,0BAA0B,iHAKtC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,UAW1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,mXAc7B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,UAItB,CAAC;AAEF;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE;IAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GAAG,IAAI,CAYzE;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,UAQtB,CAAC"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite schema definitions for OpenTasks
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Create nodes table
|
|
6
|
+
*/
|
|
7
|
+
export const CREATE_NODES_TABLE = `
|
|
8
|
+
CREATE TABLE IF NOT EXISTS nodes (
|
|
9
|
+
id TEXT PRIMARY KEY,
|
|
10
|
+
uuid TEXT UNIQUE NOT NULL,
|
|
11
|
+
type TEXT NOT NULL,
|
|
12
|
+
title TEXT NOT NULL,
|
|
13
|
+
content TEXT,
|
|
14
|
+
content_hash TEXT,
|
|
15
|
+
status TEXT,
|
|
16
|
+
priority INTEGER,
|
|
17
|
+
assignee TEXT,
|
|
18
|
+
parent_id TEXT,
|
|
19
|
+
source TEXT,
|
|
20
|
+
archived INTEGER DEFAULT 0,
|
|
21
|
+
created_at TEXT NOT NULL,
|
|
22
|
+
updated_at TEXT NOT NULL,
|
|
23
|
+
|
|
24
|
+
-- Feedback fields
|
|
25
|
+
target_id TEXT,
|
|
26
|
+
feedback_type TEXT,
|
|
27
|
+
thread_id TEXT,
|
|
28
|
+
reply_to_id TEXT,
|
|
29
|
+
resolved INTEGER,
|
|
30
|
+
dismissed INTEGER,
|
|
31
|
+
|
|
32
|
+
-- External fields
|
|
33
|
+
uri TEXT,
|
|
34
|
+
materialized INTEGER,
|
|
35
|
+
cached_at TEXT,
|
|
36
|
+
stale INTEGER,
|
|
37
|
+
external_status TEXT,
|
|
38
|
+
|
|
39
|
+
-- Coordination
|
|
40
|
+
claimed_by TEXT,
|
|
41
|
+
claimed_at TEXT,
|
|
42
|
+
lock_until TEXT,
|
|
43
|
+
|
|
44
|
+
-- Context
|
|
45
|
+
location TEXT,
|
|
46
|
+
branch TEXT,
|
|
47
|
+
|
|
48
|
+
FOREIGN KEY (parent_id) REFERENCES nodes(id)
|
|
49
|
+
)
|
|
50
|
+
`;
|
|
51
|
+
/**
|
|
52
|
+
* Create tags join table
|
|
53
|
+
*/
|
|
54
|
+
export const CREATE_NODE_TAGS_TABLE = `
|
|
55
|
+
CREATE TABLE IF NOT EXISTS node_tags (
|
|
56
|
+
node_id TEXT NOT NULL,
|
|
57
|
+
tag TEXT NOT NULL,
|
|
58
|
+
PRIMARY KEY (node_id, tag),
|
|
59
|
+
FOREIGN KEY (node_id) REFERENCES nodes(id) ON DELETE CASCADE
|
|
60
|
+
)
|
|
61
|
+
`;
|
|
62
|
+
/**
|
|
63
|
+
* Create edges table
|
|
64
|
+
*/
|
|
65
|
+
export const CREATE_EDGES_TABLE = `
|
|
66
|
+
CREATE TABLE IF NOT EXISTS edges (
|
|
67
|
+
id TEXT PRIMARY KEY,
|
|
68
|
+
uuid TEXT UNIQUE NOT NULL,
|
|
69
|
+
from_id TEXT NOT NULL,
|
|
70
|
+
to_id TEXT NOT NULL,
|
|
71
|
+
type TEXT NOT NULL,
|
|
72
|
+
created_at TEXT NOT NULL,
|
|
73
|
+
created_by TEXT,
|
|
74
|
+
source TEXT,
|
|
75
|
+
metadata TEXT,
|
|
76
|
+
cached_at TEXT
|
|
77
|
+
)
|
|
78
|
+
`;
|
|
79
|
+
/**
|
|
80
|
+
* Create dirty tracking table
|
|
81
|
+
*/
|
|
82
|
+
export const CREATE_DIRTY_NODES_TABLE = `
|
|
83
|
+
CREATE TABLE IF NOT EXISTS dirty_nodes (
|
|
84
|
+
node_id TEXT PRIMARY KEY,
|
|
85
|
+
marked_at TEXT NOT NULL
|
|
86
|
+
)
|
|
87
|
+
`;
|
|
88
|
+
/**
|
|
89
|
+
* Create export hashes table
|
|
90
|
+
*/
|
|
91
|
+
export const CREATE_EXPORT_HASHES_TABLE = `
|
|
92
|
+
CREATE TABLE IF NOT EXISTS export_hashes (
|
|
93
|
+
node_id TEXT PRIMARY KEY,
|
|
94
|
+
content_hash TEXT NOT NULL
|
|
95
|
+
)
|
|
96
|
+
`;
|
|
97
|
+
/**
|
|
98
|
+
* Create indexes
|
|
99
|
+
*/
|
|
100
|
+
export const CREATE_INDEXES = [
|
|
101
|
+
'CREATE INDEX IF NOT EXISTS idx_nodes_type ON nodes(type)',
|
|
102
|
+
'CREATE INDEX IF NOT EXISTS idx_nodes_status ON nodes(status)',
|
|
103
|
+
'CREATE INDEX IF NOT EXISTS idx_nodes_parent ON nodes(parent_id)',
|
|
104
|
+
'CREATE INDEX IF NOT EXISTS idx_nodes_archived ON nodes(archived)',
|
|
105
|
+
'CREATE INDEX IF NOT EXISTS idx_node_tags_tag ON node_tags(tag)',
|
|
106
|
+
'CREATE INDEX IF NOT EXISTS idx_edges_from ON edges(from_id)',
|
|
107
|
+
'CREATE INDEX IF NOT EXISTS idx_edges_to ON edges(to_id)',
|
|
108
|
+
'CREATE INDEX IF NOT EXISTS idx_edges_type ON edges(type)',
|
|
109
|
+
'CREATE INDEX IF NOT EXISTS idx_edges_source ON edges(source)',
|
|
110
|
+
'CREATE INDEX IF NOT EXISTS idx_edges_cached_at ON edges(cached_at)',
|
|
111
|
+
];
|
|
112
|
+
/**
|
|
113
|
+
* Create ready_tasks view
|
|
114
|
+
* Shows tasks that are open, not archived, and have no open blockers
|
|
115
|
+
*/
|
|
116
|
+
export const CREATE_READY_VIEW = `
|
|
117
|
+
CREATE VIEW IF NOT EXISTS ready_tasks AS
|
|
118
|
+
SELECT n.* FROM nodes n
|
|
119
|
+
WHERE n.type = 'task'
|
|
120
|
+
AND n.status = 'open'
|
|
121
|
+
AND n.archived = 0
|
|
122
|
+
AND NOT EXISTS (
|
|
123
|
+
SELECT 1 FROM edges e
|
|
124
|
+
JOIN nodes blocker ON e.from_id = blocker.id
|
|
125
|
+
WHERE e.to_id = n.id
|
|
126
|
+
AND e.type = 'blocks'
|
|
127
|
+
AND blocker.status != 'closed'
|
|
128
|
+
AND blocker.archived = 0
|
|
129
|
+
)
|
|
130
|
+
`;
|
|
131
|
+
/**
|
|
132
|
+
* Migration statements for existing databases
|
|
133
|
+
* These are idempotent (safe to run multiple times)
|
|
134
|
+
*/
|
|
135
|
+
export const MIGRATIONS = [
|
|
136
|
+
// Add metadata and cached_at columns to edges table (v1.1.0)
|
|
137
|
+
`ALTER TABLE edges ADD COLUMN metadata TEXT`,
|
|
138
|
+
`ALTER TABLE edges ADD COLUMN cached_at TEXT`,
|
|
139
|
+
];
|
|
140
|
+
/**
|
|
141
|
+
* Apply migrations safely (ignores "duplicate column" errors)
|
|
142
|
+
*/
|
|
143
|
+
export function applyMigrations(db) {
|
|
144
|
+
for (const migration of MIGRATIONS) {
|
|
145
|
+
try {
|
|
146
|
+
db.exec(migration);
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
// Ignore "duplicate column name" errors (migration already applied)
|
|
150
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
151
|
+
if (!message.includes('duplicate column name')) {
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* All schema creation statements in order
|
|
159
|
+
*/
|
|
160
|
+
export const ALL_SCHEMA = [
|
|
161
|
+
CREATE_NODES_TABLE,
|
|
162
|
+
CREATE_NODE_TAGS_TABLE,
|
|
163
|
+
CREATE_EDGES_TABLE,
|
|
164
|
+
CREATE_DIRTY_NODES_TABLE,
|
|
165
|
+
CREATE_EXPORT_HASHES_TABLE,
|
|
166
|
+
...CREATE_INDEXES,
|
|
167
|
+
CREATE_READY_VIEW,
|
|
168
|
+
];
|
|
169
|
+
//# sourceMappingURL=sqlite-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-schema.js","sourceRoot":"","sources":["../../src/storage/sqlite-schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2CjC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;CAOrC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;CAajC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG;;;;;CAKvC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;;;;;CAKzC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,0DAA0D;IAC1D,8DAA8D;IAC9D,iEAAiE;IACjE,kEAAkE;IAClE,gEAAgE;IAChE,6DAA6D;IAC7D,yDAAyD;IACzD,0DAA0D;IAC1D,8DAA8D;IAC9D,oEAAoE;CACrE,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;CAchC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,6DAA6D;IAC7D,4CAA4C;IAC5C,6CAA6C;CAC9C,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,EAAmC;IACjE,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,oEAAoE;YACpE,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC;gBAC/C,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,kBAAkB;IAClB,sBAAsB;IACtB,kBAAkB;IAClB,wBAAwB;IACxB,0BAA0B;IAC1B,GAAG,cAAc;IACjB,iBAAiB;CAClB,CAAC"}
|