dotdo 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +446 -315
- package/dist/ai/index.js +19 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/template-literals.js +852 -0
- package/dist/ai/template-literals.js.map +1 -0
- package/dist/api/analytics/router.js +601 -0
- package/dist/api/analytics/router.js.map +1 -0
- package/dist/api/index.js +158 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/middleware/auth-federation.js +573 -0
- package/dist/api/middleware/auth-federation.js.map +1 -0
- package/dist/api/middleware/auth.js +544 -0
- package/dist/api/middleware/auth.js.map +1 -0
- package/dist/api/middleware/error-handling.js +176 -0
- package/dist/api/middleware/error-handling.js.map +1 -0
- package/dist/api/middleware/request-id.js +21 -0
- package/dist/api/middleware/request-id.js.map +1 -0
- package/dist/api/pages.js +1180 -0
- package/dist/api/pages.js.map +1 -0
- package/dist/api/routes/api.js +612 -0
- package/dist/api/routes/api.js.map +1 -0
- package/dist/api/routes/browsers.js +471 -0
- package/dist/api/routes/browsers.js.map +1 -0
- package/dist/api/routes/do.js +188 -0
- package/dist/api/routes/do.js.map +1 -0
- package/dist/api/routes/mcp.js +459 -0
- package/dist/api/routes/mcp.js.map +1 -0
- package/dist/api/routes/obs.js +445 -0
- package/dist/api/routes/obs.js.map +1 -0
- package/dist/api/routes/openapi.js +794 -0
- package/dist/api/routes/openapi.js.map +1 -0
- package/dist/api/routes/rpc.js +1103 -0
- package/dist/api/routes/rpc.js.map +1 -0
- package/dist/api/routes/sandboxes.js +389 -0
- package/dist/api/routes/sandboxes.js.map +1 -0
- package/dist/api/test-do.js +38 -0
- package/dist/api/test-do.js.map +1 -0
- package/dist/api/types.js +11 -0
- package/dist/api/types.js.map +1 -0
- package/dist/cli/bin.js +2 -0
- package/dist/cli/main.js +52342 -0
- package/dist/db/actions.js +212 -0
- package/dist/db/actions.js.map +1 -0
- package/dist/db/auth.js +506 -0
- package/dist/db/auth.js.map +1 -0
- package/dist/db/branches.js +65 -0
- package/dist/db/branches.js.map +1 -0
- package/dist/db/clickhouse.js +1074 -0
- package/dist/db/clickhouse.js.map +1 -0
- package/dist/db/dlq.js +39 -0
- package/dist/db/dlq.js.map +1 -0
- package/dist/db/events.js +28 -0
- package/dist/db/events.js.map +1 -0
- package/dist/db/exec.js +64 -0
- package/dist/db/exec.js.map +1 -0
- package/dist/db/files.js +85 -0
- package/dist/db/files.js.map +1 -0
- package/dist/db/flags.js +24 -0
- package/dist/db/flags.js.map +1 -0
- package/dist/db/git.js +116 -0
- package/dist/db/git.js.map +1 -0
- package/dist/db/iceberg/inverted-index.js +862 -0
- package/dist/db/iceberg/inverted-index.js.map +1 -0
- package/dist/db/iceberg/puffin.js +878 -0
- package/dist/db/iceberg/puffin.js.map +1 -0
- package/dist/db/iceberg/search-manifest.js +422 -0
- package/dist/db/iceberg/search-manifest.js.map +1 -0
- package/dist/db/iceberg/types.js +8 -0
- package/dist/db/iceberg/types.js.map +1 -0
- package/dist/db/index.js +121 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/integrations.js +368 -0
- package/dist/db/integrations.js.map +1 -0
- package/dist/db/json-indexes.js +332 -0
- package/dist/db/json-indexes.js.map +1 -0
- package/dist/db/linked-accounts.js +287 -0
- package/dist/db/linked-accounts.js.map +1 -0
- package/dist/db/nouns.js +183 -0
- package/dist/db/nouns.js.map +1 -0
- package/dist/db/objects.js +170 -0
- package/dist/db/objects.js.map +1 -0
- package/dist/db/primitives/dag-scheduler/index.js +869 -0
- package/dist/db/primitives/dag-scheduler/index.js.map +1 -0
- package/dist/db/primitives/exactly-once-context.js +237 -0
- package/dist/db/primitives/exactly-once-context.js.map +1 -0
- package/dist/db/primitives/index.js +62 -0
- package/dist/db/primitives/index.js.map +1 -0
- package/dist/db/primitives/keyed-router.js +145 -0
- package/dist/db/primitives/keyed-router.js.map +1 -0
- package/dist/db/primitives/observability.js +162 -0
- package/dist/db/primitives/observability.js.map +1 -0
- package/dist/db/primitives/schema-evolution.js +643 -0
- package/dist/db/primitives/schema-evolution.js.map +1 -0
- package/dist/db/primitives/stateful-operator/index.js +770 -0
- package/dist/db/primitives/stateful-operator/index.js.map +1 -0
- package/dist/db/primitives/temporal-store.js +306 -0
- package/dist/db/primitives/temporal-store.js.map +1 -0
- package/dist/db/primitives/typed-column-store.js +1229 -0
- package/dist/db/primitives/typed-column-store.js.map +1 -0
- package/dist/db/primitives/utils/duration.js +162 -0
- package/dist/db/primitives/utils/duration.js.map +1 -0
- package/dist/db/primitives/utils/murmur3.js +118 -0
- package/dist/db/primitives/utils/murmur3.js.map +1 -0
- package/dist/db/primitives/watermark-service.js +136 -0
- package/dist/db/primitives/watermark-service.js.map +1 -0
- package/dist/db/primitives/window-manager.js +764 -0
- package/dist/db/primitives/window-manager.js.map +1 -0
- package/dist/db/relationships.js +66 -0
- package/dist/db/relationships.js.map +1 -0
- package/dist/db/schema-minimal.js +61 -0
- package/dist/db/schema-minimal.js.map +1 -0
- package/dist/db/search.js +28 -0
- package/dist/db/search.js.map +1 -0
- package/dist/db/stores.js +1665 -0
- package/dist/db/stores.js.map +1 -0
- package/dist/db/things.js +297 -0
- package/dist/db/things.js.map +1 -0
- package/dist/db/vault.js +171 -0
- package/dist/db/vault.js.map +1 -0
- package/dist/db/verbs.js +102 -0
- package/dist/db/verbs.js.map +1 -0
- package/dist/do/base.js +48 -0
- package/dist/do/base.js.map +1 -0
- package/dist/do/bash.js +35 -0
- package/dist/do/bash.js.map +1 -0
- package/dist/do/fs.js +25 -0
- package/dist/do/fs.js.map +1 -0
- package/dist/do/full.js +61 -0
- package/dist/do/full.js.map +1 -0
- package/dist/do/git.js +28 -0
- package/dist/do/git.js.map +1 -0
- package/dist/do/index.js +52 -0
- package/dist/do/index.js.map +1 -0
- package/dist/do/tiny.js +31 -0
- package/dist/do/tiny.js.map +1 -0
- package/dist/lib/DOAuth.js +261 -0
- package/dist/lib/DOAuth.js.map +1 -0
- package/dist/lib/DODispatcher.js +72 -0
- package/dist/lib/DODispatcher.js.map +1 -0
- package/dist/lib/Modifier.js +189 -0
- package/dist/lib/Modifier.js.map +1 -0
- package/dist/lib/StateStorage.js +403 -0
- package/dist/lib/StateStorage.js.map +1 -0
- package/dist/lib/TypeRegistry.js +122 -0
- package/dist/lib/TypeRegistry.js.map +1 -0
- package/dist/lib/agent/tools/bash.js +336 -0
- package/dist/lib/agent/tools/bash.js.map +1 -0
- package/dist/lib/agent/tools/edit.js +157 -0
- package/dist/lib/agent/tools/edit.js.map +1 -0
- package/dist/lib/agent/tools/glob.js +137 -0
- package/dist/lib/agent/tools/glob.js.map +1 -0
- package/dist/lib/agent/tools/grep.js +315 -0
- package/dist/lib/agent/tools/grep.js.map +1 -0
- package/dist/lib/agent/tools/index.js +71 -0
- package/dist/lib/agent/tools/index.js.map +1 -0
- package/dist/lib/agent/tools/read.js +212 -0
- package/dist/lib/agent/tools/read.js.map +1 -0
- package/dist/lib/agent/tools/types.js +197 -0
- package/dist/lib/agent/tools/types.js.map +1 -0
- package/dist/lib/agent/tools/write.js +159 -0
- package/dist/lib/agent/tools/write.js.map +1 -0
- package/dist/lib/ai/gateway.js +247 -0
- package/dist/lib/ai/gateway.js.map +1 -0
- package/dist/lib/ai/tool-loop-agent.js +591 -0
- package/dist/lib/ai/tool-loop-agent.js.map +1 -0
- package/dist/lib/auto-wiring.js +439 -0
- package/dist/lib/auto-wiring.js.map +1 -0
- package/dist/lib/browse/browserbase.js +163 -0
- package/dist/lib/browse/browserbase.js.map +1 -0
- package/dist/lib/browse/cloudflare.js +144 -0
- package/dist/lib/browse/cloudflare.js.map +1 -0
- package/dist/lib/browse/index.js +62 -0
- package/dist/lib/browse/index.js.map +1 -0
- package/dist/lib/browse/types.js +13 -0
- package/dist/lib/browse/types.js.map +1 -0
- package/dist/lib/cache/index.js +37 -0
- package/dist/lib/cache/index.js.map +1 -0
- package/dist/lib/cache/visibility.js +638 -0
- package/dist/lib/cache/visibility.js.map +1 -0
- package/dist/lib/capabilities.js +268 -0
- package/dist/lib/capabilities.js.map +1 -0
- package/dist/lib/channels/base.js +106 -0
- package/dist/lib/channels/base.js.map +1 -0
- package/dist/lib/channels/discord.js +94 -0
- package/dist/lib/channels/discord.js.map +1 -0
- package/dist/lib/channels/email.js +204 -0
- package/dist/lib/channels/email.js.map +1 -0
- package/dist/lib/channels/index.js +90 -0
- package/dist/lib/channels/index.js.map +1 -0
- package/dist/lib/channels/mdxui-chat.js +95 -0
- package/dist/lib/channels/mdxui-chat.js.map +1 -0
- package/dist/lib/channels/slack-blockkit.js +121 -0
- package/dist/lib/channels/slack-blockkit.js.map +1 -0
- package/dist/lib/channels/types.js +7 -0
- package/dist/lib/channels/types.js.map +1 -0
- package/dist/lib/cloudflare/ai.js +654 -0
- package/dist/lib/cloudflare/ai.js.map +1 -0
- package/dist/lib/cloudflare/index.js +88 -0
- package/dist/lib/cloudflare/index.js.map +1 -0
- package/dist/lib/cloudflare/kv.js +342 -0
- package/dist/lib/cloudflare/kv.js.map +1 -0
- package/dist/lib/cloudflare/queues.js +434 -0
- package/dist/lib/cloudflare/queues.js.map +1 -0
- package/dist/lib/cloudflare/r2.js +604 -0
- package/dist/lib/cloudflare/r2.js.map +1 -0
- package/dist/lib/cloudflare/vectorize.js +494 -0
- package/dist/lib/cloudflare/vectorize.js.map +1 -0
- package/dist/lib/cloudflare/workflows.js +569 -0
- package/dist/lib/cloudflare/workflows.js.map +1 -0
- package/dist/lib/colo/caching.js +196 -0
- package/dist/lib/colo/caching.js.map +1 -0
- package/dist/lib/colo/detection.js +194 -0
- package/dist/lib/colo/detection.js.map +1 -0
- package/dist/lib/colo/external-data.js +219 -0
- package/dist/lib/colo/external-data.js.map +1 -0
- package/dist/lib/colo/globe-data.js +179 -0
- package/dist/lib/colo/globe-data.js.map +1 -0
- package/dist/lib/colo/index.js +16 -0
- package/dist/lib/colo/index.js.map +1 -0
- package/dist/lib/decorators.js +37 -0
- package/dist/lib/decorators.js.map +1 -0
- package/dist/lib/discovery.js +81 -0
- package/dist/lib/discovery.js.map +1 -0
- package/dist/lib/executors/AgenticFunctionExecutor.js +619 -0
- package/dist/lib/executors/AgenticFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/BaseFunctionExecutor.js +328 -0
- package/dist/lib/executors/BaseFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/CascadeExecutor.js +418 -0
- package/dist/lib/executors/CascadeExecutor.js.map +1 -0
- package/dist/lib/executors/CodeFunctionExecutor.js +904 -0
- package/dist/lib/executors/CodeFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/GenerativeFunctionExecutor.js +904 -0
- package/dist/lib/executors/GenerativeFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/HumanFunctionExecutor.js +884 -0
- package/dist/lib/executors/HumanFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/ParallelStepExecutor.js +308 -0
- package/dist/lib/executors/ParallelStepExecutor.js.map +1 -0
- package/dist/lib/executors/types.js +12 -0
- package/dist/lib/executors/types.js.map +1 -0
- package/dist/lib/experiments.js +89 -0
- package/dist/lib/experiments.js.map +1 -0
- package/dist/lib/flags/store.js +262 -0
- package/dist/lib/flags/store.js.map +1 -0
- package/dist/lib/functions/FunctionComposition.js +467 -0
- package/dist/lib/functions/FunctionComposition.js.map +1 -0
- package/dist/lib/functions/FunctionMiddleware.js +457 -0
- package/dist/lib/functions/FunctionMiddleware.js.map +1 -0
- package/dist/lib/functions/FunctionRegistry.js +426 -0
- package/dist/lib/functions/FunctionRegistry.js.map +1 -0
- package/dist/lib/functions/createFunction.js +1048 -0
- package/dist/lib/functions/createFunction.js.map +1 -0
- package/dist/lib/humans/index.js +68 -0
- package/dist/lib/humans/index.js.map +1 -0
- package/dist/lib/humans/templates.js +117 -0
- package/dist/lib/humans/templates.js.map +1 -0
- package/dist/lib/identity.js +98 -0
- package/dist/lib/identity.js.map +1 -0
- package/dist/lib/index.js +9 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/logging/error-logger.js +163 -0
- package/dist/lib/logging/error-logger.js.map +1 -0
- package/dist/lib/logging/index.js +160 -0
- package/dist/lib/logging/index.js.map +1 -0
- package/dist/lib/mixins/bash.js +825 -0
- package/dist/lib/mixins/bash.js.map +1 -0
- package/dist/lib/mixins/fs.js +648 -0
- package/dist/lib/mixins/fs.js.map +1 -0
- package/dist/lib/mixins/git.js +1011 -0
- package/dist/lib/mixins/git.js.map +1 -0
- package/dist/lib/mixins/index.js +29 -0
- package/dist/lib/mixins/index.js.map +1 -0
- package/dist/lib/mixins/npm.js +662 -0
- package/dist/lib/mixins/npm.js.map +1 -0
- package/dist/lib/noun-id.js +278 -0
- package/dist/lib/noun-id.js.map +1 -0
- package/dist/lib/rate-limit/sliding-window.js +148 -0
- package/dist/lib/rate-limit/sliding-window.js.map +1 -0
- package/dist/lib/rate-limit.js +110 -0
- package/dist/lib/rate-limit.js.map +1 -0
- package/dist/lib/rpc/bindings.js +548 -0
- package/dist/lib/rpc/bindings.js.map +1 -0
- package/dist/lib/rpc/index.js +64 -0
- package/dist/lib/rpc/index.js.map +1 -0
- package/dist/lib/safe-stringify.js +223 -0
- package/dist/lib/safe-stringify.js.map +1 -0
- package/dist/lib/sandbox/miniflare-sandbox.js +1007 -0
- package/dist/lib/sandbox/miniflare-sandbox.js.map +1 -0
- package/dist/lib/sqids.js +110 -0
- package/dist/lib/sqids.js.map +1 -0
- package/dist/lib/sql/adapters/index.js +10 -0
- package/dist/lib/sql/adapters/index.js.map +1 -0
- package/dist/lib/sql/adapters/node-sql-parser.js +552 -0
- package/dist/lib/sql/adapters/node-sql-parser.js.map +1 -0
- package/dist/lib/sql/adapters/pgsql-parser.js +1189 -0
- package/dist/lib/sql/adapters/pgsql-parser.js.map +1 -0
- package/dist/lib/sql/index.js +277 -0
- package/dist/lib/sql/index.js.map +1 -0
- package/dist/lib/sql/types.js +56 -0
- package/dist/lib/sql/types.js.map +1 -0
- package/dist/lib/type-classifier.js +126 -0
- package/dist/lib/type-classifier.js.map +1 -0
- package/dist/lib/utils/html.js +47 -0
- package/dist/lib/utils/html.js.map +1 -0
- package/dist/lib/validation.js +48 -0
- package/dist/lib/validation.js.map +1 -0
- package/dist/lib/vault/store.js +411 -0
- package/dist/lib/vault/store.js.map +1 -0
- package/dist/metrics/hunch.js +739 -0
- package/dist/metrics/hunch.js.map +1 -0
- package/dist/objects/API.js +302 -0
- package/dist/objects/API.js.map +1 -0
- package/dist/objects/Agent.js +179 -0
- package/dist/objects/Agent.js.map +1 -0
- package/dist/objects/AgenticFunctionExecutor.js +8 -0
- package/dist/objects/AgenticFunctionExecutor.js.map +1 -0
- package/dist/objects/App.js +83 -0
- package/dist/objects/App.js.map +1 -0
- package/dist/objects/Browser.js +884 -0
- package/dist/objects/Browser.js.map +1 -0
- package/dist/objects/Business.js +107 -0
- package/dist/objects/Business.js.map +1 -0
- package/dist/objects/CLI.js +221 -0
- package/dist/objects/CLI.js.map +1 -0
- package/dist/objects/CodeFunctionExecutor.js +8 -0
- package/dist/objects/CodeFunctionExecutor.js.map +1 -0
- package/dist/objects/Collection.js +161 -0
- package/dist/objects/Collection.js.map +1 -0
- package/dist/objects/DO.js +41 -0
- package/dist/objects/DO.js.map +1 -0
- package/dist/objects/DOBase.js +2309 -0
- package/dist/objects/DOBase.js.map +1 -0
- package/dist/objects/DOFull.js +1676 -0
- package/dist/objects/DOFull.js.map +1 -0
- package/dist/objects/DOTiny.js +207 -0
- package/dist/objects/DOTiny.js.map +1 -0
- package/dist/objects/Directory.js +199 -0
- package/dist/objects/Directory.js.map +1 -0
- package/dist/objects/Entity.js +413 -0
- package/dist/objects/Entity.js.map +1 -0
- package/dist/objects/Function.js +116 -0
- package/dist/objects/Function.js.map +1 -0
- package/dist/objects/Human.js +231 -0
- package/dist/objects/Human.js.map +1 -0
- package/dist/objects/HumanFunctionExecutor.js +8 -0
- package/dist/objects/HumanFunctionExecutor.js.map +1 -0
- package/dist/objects/IcebergMetadataDO.js +938 -0
- package/dist/objects/IcebergMetadataDO.js.map +1 -0
- package/dist/objects/IntegrationsDO.js +1174 -0
- package/dist/objects/IntegrationsDO.js.map +1 -0
- package/dist/objects/ObservabilityBroadcaster.js +149 -0
- package/dist/objects/ObservabilityBroadcaster.js.map +1 -0
- package/dist/objects/Package.js +154 -0
- package/dist/objects/Package.js.map +1 -0
- package/dist/objects/Product.js +193 -0
- package/dist/objects/Product.js.map +1 -0
- package/dist/objects/SDK.js +152 -0
- package/dist/objects/SDK.js.map +1 -0
- package/dist/objects/SaaS.js +235 -0
- package/dist/objects/SaaS.js.map +1 -0
- package/dist/objects/SandboxDO.js +759 -0
- package/dist/objects/SandboxDO.js.map +1 -0
- package/dist/objects/Service.js +337 -0
- package/dist/objects/Service.js.map +1 -0
- package/dist/objects/Site.js +80 -0
- package/dist/objects/Site.js.map +1 -0
- package/dist/objects/Startup.js +479 -0
- package/dist/objects/Startup.js.map +1 -0
- package/dist/objects/ThingsDO.js +170 -0
- package/dist/objects/ThingsDO.js.map +1 -0
- package/dist/objects/VectorShardDO.js +648 -0
- package/dist/objects/VectorShardDO.js.map +1 -0
- package/dist/objects/Worker.js +144 -0
- package/dist/objects/Worker.js.map +1 -0
- package/dist/objects/Workflow.js +196 -0
- package/dist/objects/Workflow.js.map +1 -0
- package/dist/objects/WorkflowFactory.js +313 -0
- package/dist/objects/WorkflowFactory.js.map +1 -0
- package/dist/objects/WorkflowRuntime.js +863 -0
- package/dist/objects/WorkflowRuntime.js.map +1 -0
- package/dist/objects/circuit-breaker-bulkhead.js +178 -0
- package/dist/objects/circuit-breaker-bulkhead.js.map +1 -0
- package/dist/objects/createFunction.js +934 -0
- package/dist/objects/createFunction.js.map +1 -0
- package/dist/objects/index.js +80 -0
- package/dist/objects/index.js.map +1 -0
- package/dist/objects/lifecycle/Branch.js +275 -0
- package/dist/objects/lifecycle/Branch.js.map +1 -0
- package/dist/objects/lifecycle/Clone.js +1499 -0
- package/dist/objects/lifecycle/Clone.js.map +1 -0
- package/dist/objects/lifecycle/Compact.js +237 -0
- package/dist/objects/lifecycle/Compact.js.map +1 -0
- package/dist/objects/lifecycle/Promote.js +476 -0
- package/dist/objects/lifecycle/Promote.js.map +1 -0
- package/dist/objects/lifecycle/Shard.js +560 -0
- package/dist/objects/lifecycle/Shard.js.map +1 -0
- package/dist/objects/lifecycle/index.js +15 -0
- package/dist/objects/lifecycle/index.js.map +1 -0
- package/dist/objects/lifecycle/types.js +33 -0
- package/dist/objects/lifecycle/types.js.map +1 -0
- package/dist/objects/mixins/infrastructure.js +171 -0
- package/dist/objects/mixins/infrastructure.js.map +1 -0
- package/dist/objects/modules/StoresModule.js +153 -0
- package/dist/objects/modules/StoresModule.js.map +1 -0
- package/dist/objects/persistence/checkpoint-manager.js +606 -0
- package/dist/objects/persistence/checkpoint-manager.js.map +1 -0
- package/dist/objects/persistence/index.js +72 -0
- package/dist/objects/persistence/index.js.map +1 -0
- package/dist/objects/persistence/migration-runner.js +562 -0
- package/dist/objects/persistence/migration-runner.js.map +1 -0
- package/dist/objects/persistence/replication-manager.js +501 -0
- package/dist/objects/persistence/replication-manager.js.map +1 -0
- package/dist/objects/persistence/tiered-storage-manager.js +595 -0
- package/dist/objects/persistence/tiered-storage-manager.js.map +1 -0
- package/dist/objects/persistence/types.js +14 -0
- package/dist/objects/persistence/types.js.map +1 -0
- package/dist/objects/persistence/wal-manager.js +653 -0
- package/dist/objects/persistence/wal-manager.js.map +1 -0
- package/dist/objects/presets/index.js +20 -0
- package/dist/objects/presets/index.js.map +1 -0
- package/dist/objects/presets/primitives.js +188 -0
- package/dist/objects/presets/primitives.js.map +1 -0
- package/dist/objects/primitives/alarm-adapter.js +141 -0
- package/dist/objects/primitives/alarm-adapter.js.map +1 -0
- package/dist/objects/primitives/index.js +337 -0
- package/dist/objects/primitives/index.js.map +1 -0
- package/dist/objects/primitives/storage-adapter.js +182 -0
- package/dist/objects/primitives/storage-adapter.js.map +1 -0
- package/dist/objects/primitives/with-primitives.js +102 -0
- package/dist/objects/primitives/with-primitives.js.map +1 -0
- package/dist/objects/services/StoreManager.js +227 -0
- package/dist/objects/services/StoreManager.js.map +1 -0
- package/dist/objects/services/index.js +13 -0
- package/dist/objects/services/index.js.map +1 -0
- package/dist/objects/transport/auth-layer.js +1451 -0
- package/dist/objects/transport/auth-layer.js.map +1 -0
- package/dist/objects/transport/capnweb-target.js +355 -0
- package/dist/objects/transport/capnweb-target.js.map +1 -0
- package/dist/objects/transport/chain.js +441 -0
- package/dist/objects/transport/chain.js.map +1 -0
- package/dist/objects/transport/handler.js +58 -0
- package/dist/objects/transport/handler.js.map +1 -0
- package/dist/objects/transport/index.js +53 -0
- package/dist/objects/transport/index.js.map +1 -0
- package/dist/objects/transport/mcp-server.js +690 -0
- package/dist/objects/transport/mcp-server.js.map +1 -0
- package/dist/objects/transport/rest-autowire.js +1507 -0
- package/dist/objects/transport/rest-autowire.js.map +1 -0
- package/dist/objects/transport/rest-router.js +440 -0
- package/dist/objects/transport/rest-router.js.map +1 -0
- package/dist/objects/transport/rpc-server.js +1536 -0
- package/dist/objects/transport/rpc-server.js.map +1 -0
- package/dist/objects/transport/shared.js +575 -0
- package/dist/objects/transport/shared.js.map +1 -0
- package/dist/objects/transport/sync-engine.js +291 -0
- package/dist/objects/transport/sync-engine.js.map +1 -0
- package/dist/objects/transport/types.js +8 -0
- package/dist/objects/transport/types.js.map +1 -0
- package/dist/primitives/bashx/src/ast/analyze.js +1472 -0
- package/dist/primitives/bashx/src/ast/analyze.js.map +1 -0
- package/dist/primitives/bashx/src/ast/parser.js +1488 -0
- package/dist/primitives/bashx/src/ast/parser.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/crypto.js +1954 -0
- package/dist/primitives/bashx/src/do/commands/crypto.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/data-processing.js +1812 -0
- package/dist/primitives/bashx/src/do/commands/data-processing.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/extended-utils.js +804 -0
- package/dist/primitives/bashx/src/do/commands/extended-utils.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/math-control.js +1122 -0
- package/dist/primitives/bashx/src/do/commands/math-control.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/posix-utils.js +1015 -0
- package/dist/primitives/bashx/src/do/commands/posix-utils.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/system-utils.js +687 -0
- package/dist/primitives/bashx/src/do/commands/system-utils.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/test-command.js +523 -0
- package/dist/primitives/bashx/src/do/commands/test-command.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/text-processing.js +1550 -0
- package/dist/primitives/bashx/src/do/commands/text-processing.js.map +1 -0
- package/dist/primitives/bashx/src/do/container-executor.js +429 -0
- package/dist/primitives/bashx/src/do/container-executor.js.map +1 -0
- package/dist/primitives/bashx/src/do/index.js +668 -0
- package/dist/primitives/bashx/src/do/index.js.map +1 -0
- package/dist/primitives/bashx/src/do/tiered-executor.js +2647 -0
- package/dist/primitives/bashx/src/do/tiered-executor.js.map +1 -0
- package/dist/primitives/bashx/src/do/worker.js +352 -0
- package/dist/primitives/bashx/src/do/worker.js.map +1 -0
- package/dist/primitives/bashx/src/types.js +10 -0
- package/dist/primitives/bashx/src/types.js.map +1 -0
- package/dist/primitives/fsx/core/backend.js +480 -0
- package/dist/primitives/fsx/core/backend.js.map +1 -0
- package/dist/primitives/fsx/core/constants.js +140 -0
- package/dist/primitives/fsx/core/constants.js.map +1 -0
- package/dist/primitives/fsx/core/fsx.js +1184 -0
- package/dist/primitives/fsx/core/fsx.js.map +1 -0
- package/dist/primitives/fsx/core/glob/glob.js +438 -0
- package/dist/primitives/fsx/core/glob/glob.js.map +1 -0
- package/dist/primitives/fsx/core/glob/index.js +8 -0
- package/dist/primitives/fsx/core/glob/index.js.map +1 -0
- package/dist/primitives/fsx/core/glob/match.js +392 -0
- package/dist/primitives/fsx/core/glob/match.js.map +1 -0
- package/dist/primitives/fsx/core/types.js +307 -0
- package/dist/primitives/fsx/core/types.js.map +1 -0
- package/dist/sandbox/index.js +258 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/sdk/capnweb-compat.js +42 -0
- package/dist/sdk/capnweb-compat.js.map +1 -0
- package/dist/sdk/client.js +20 -0
- package/dist/sdk/client.js.map +1 -0
- package/dist/sdk/index.js +17 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/snippets/artifacts-config.js +241 -0
- package/dist/snippets/artifacts-config.js.map +1 -0
- package/dist/snippets/artifacts-ingest.js +832 -0
- package/dist/snippets/artifacts-ingest.js.map +1 -0
- package/dist/snippets/artifacts-serve.js +1035 -0
- package/dist/snippets/artifacts-serve.js.map +1 -0
- package/dist/snippets/artifacts-types.js +161 -0
- package/dist/snippets/artifacts-types.js.map +1 -0
- package/dist/snippets/cache-probe.js +376 -0
- package/dist/snippets/cache-probe.js.map +1 -0
- package/dist/snippets/cache.js +10 -0
- package/dist/snippets/cache.js.map +1 -0
- package/dist/snippets/events.js +469 -0
- package/dist/snippets/events.js.map +1 -0
- package/dist/snippets/index.js +7 -0
- package/dist/snippets/index.js.map +1 -0
- package/dist/snippets/proxy.js +495 -0
- package/dist/snippets/proxy.js.map +1 -0
- package/dist/snippets/search.js +1759 -0
- package/dist/snippets/search.js.map +1 -0
- package/dist/streams/index.js +30 -0
- package/dist/streams/index.js.map +1 -0
- package/dist/streams/observability.js +68 -0
- package/dist/streams/observability.js.map +1 -0
- package/dist/types/AI.js +92 -0
- package/dist/types/AI.js.map +1 -0
- package/dist/types/AIFunction.js +171 -0
- package/dist/types/AIFunction.js.map +1 -0
- package/dist/types/BrowseVerb.js +89 -0
- package/dist/types/BrowseVerb.js.map +1 -0
- package/dist/types/Browser.js +31 -0
- package/dist/types/Browser.js.map +1 -0
- package/dist/types/Chaos.js +15 -0
- package/dist/types/Chaos.js.map +1 -0
- package/dist/types/CloudflareBindings.js +109 -0
- package/dist/types/CloudflareBindings.js.map +1 -0
- package/dist/types/Collection.js +50 -0
- package/dist/types/Collection.js.map +1 -0
- package/dist/types/DO.js +2 -0
- package/dist/types/DO.js.map +1 -0
- package/dist/types/DOLocation.js +63 -0
- package/dist/types/DOLocation.js.map +1 -0
- package/dist/types/EventHandler.js +57 -0
- package/dist/types/EventHandler.js.map +1 -0
- package/dist/types/Experiment.js +33 -0
- package/dist/types/Experiment.js.map +1 -0
- package/dist/types/Flag.js +57 -0
- package/dist/types/Flag.js.map +1 -0
- package/dist/types/Lifecycle.js +13 -0
- package/dist/types/Lifecycle.js.map +1 -0
- package/dist/types/Location.js +169 -0
- package/dist/types/Location.js.map +1 -0
- package/dist/types/Noun.js +66 -0
- package/dist/types/Noun.js.map +1 -0
- package/dist/types/SessionEvent.js +194 -0
- package/dist/types/SessionEvent.js.map +1 -0
- package/dist/types/Thing.js +55 -0
- package/dist/types/Thing.js.map +1 -0
- package/dist/types/ThingDO.js +153 -0
- package/dist/types/ThingDO.js.map +1 -0
- package/dist/types/Things.js +2 -0
- package/dist/types/Things.js.map +1 -0
- package/dist/types/Verb.js +119 -0
- package/dist/types/Verb.js.map +1 -0
- package/dist/types/WorkflowContext.js +70 -0
- package/dist/types/WorkflowContext.js.map +1 -0
- package/dist/types/analytics-api.js +13 -0
- package/dist/types/analytics-api.js.map +1 -0
- package/dist/types/capabilities.js +135 -0
- package/dist/types/capabilities.js.map +1 -0
- package/dist/types/drizzle.js +12 -0
- package/dist/types/drizzle.js.map +1 -0
- package/dist/types/event.js +201 -0
- package/dist/types/event.js.map +1 -0
- package/dist/types/fn.js +12 -0
- package/dist/types/fn.js.map +1 -0
- package/dist/types/iceberg.js +48 -0
- package/dist/types/iceberg.js.map +1 -0
- package/dist/types/ids.js +170 -0
- package/dist/types/ids.js.map +1 -0
- package/dist/types/index.js +41 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/introspect.js +54 -0
- package/dist/types/introspect.js.map +1 -0
- package/dist/types/observability.js +124 -0
- package/dist/types/observability.js.map +1 -0
- package/dist/types/sync-protocol.js +175 -0
- package/dist/types/sync-protocol.js.map +1 -0
- package/dist/types/vector.js +13 -0
- package/dist/types/vector.js.map +1 -0
- package/dist/workflows/ScheduleManager.js +473 -0
- package/dist/workflows/ScheduleManager.js.map +1 -0
- package/dist/workflows/StepDOBridge.js +149 -0
- package/dist/workflows/StepDOBridge.js.map +1 -0
- package/dist/workflows/StepResultStorage.js +232 -0
- package/dist/workflows/StepResultStorage.js.map +1 -0
- package/dist/workflows/WaitForEventManager.js +461 -0
- package/dist/workflows/WaitForEventManager.js.map +1 -0
- package/dist/workflows/analyzer.js +332 -0
- package/dist/workflows/analyzer.js.map +1 -0
- package/dist/workflows/compat/activity-router.js +484 -0
- package/dist/workflows/compat/activity-router.js.map +1 -0
- package/dist/workflows/compat/backends/cloudflare-workflows.js +431 -0
- package/dist/workflows/compat/backends/cloudflare-workflows.js.map +1 -0
- package/dist/workflows/compat/backends/index.js +14 -0
- package/dist/workflows/compat/backends/index.js.map +1 -0
- package/dist/workflows/compat/errors/index.js +375 -0
- package/dist/workflows/compat/errors/index.js.map +1 -0
- package/dist/workflows/compat/index.js +79 -0
- package/dist/workflows/compat/index.js.map +1 -0
- package/dist/workflows/compat/inngest/index.js +989 -0
- package/dist/workflows/compat/inngest/index.js.map +1 -0
- package/dist/workflows/compat/qstash/index.js +1263 -0
- package/dist/workflows/compat/qstash/index.js.map +1 -0
- package/dist/workflows/compat/temporal/activities.js +739 -0
- package/dist/workflows/compat/temporal/activities.js.map +1 -0
- package/dist/workflows/compat/temporal/child-workflows.js +154 -0
- package/dist/workflows/compat/temporal/child-workflows.js.map +1 -0
- package/dist/workflows/compat/temporal/client.js +381 -0
- package/dist/workflows/compat/temporal/client.js.map +1 -0
- package/dist/workflows/compat/temporal/context.js +309 -0
- package/dist/workflows/compat/temporal/context.js.map +1 -0
- package/dist/workflows/compat/temporal/determinism.js +216 -0
- package/dist/workflows/compat/temporal/determinism.js.map +1 -0
- package/dist/workflows/compat/temporal/errors.js +128 -0
- package/dist/workflows/compat/temporal/errors.js.map +1 -0
- package/dist/workflows/compat/temporal/index.js +2464 -0
- package/dist/workflows/compat/temporal/index.js.map +1 -0
- package/dist/workflows/compat/temporal/saga.js +504 -0
- package/dist/workflows/compat/temporal/saga.js.map +1 -0
- package/dist/workflows/compat/temporal/signals.js +364 -0
- package/dist/workflows/compat/temporal/signals.js.map +1 -0
- package/dist/workflows/compat/temporal/storage.js +271 -0
- package/dist/workflows/compat/temporal/storage.js.map +1 -0
- package/dist/workflows/compat/temporal/timers.js +347 -0
- package/dist/workflows/compat/temporal/timers.js.map +1 -0
- package/dist/workflows/compat/temporal/types.js +7 -0
- package/dist/workflows/compat/temporal/types.js.map +1 -0
- package/dist/workflows/compat/temporal/unified-primitives.js +339 -0
- package/dist/workflows/compat/temporal/unified-primitives.js.map +1 -0
- package/dist/workflows/compat/trigger/index.js +468 -0
- package/dist/workflows/compat/trigger/index.js.map +1 -0
- package/dist/workflows/compat/utils/index.js +69 -0
- package/dist/workflows/compat/utils/index.js.map +1 -0
- package/dist/workflows/context/correlation-capability.js +266 -0
- package/dist/workflows/context/correlation-capability.js.map +1 -0
- package/dist/workflows/context/correlation.js +484 -0
- package/dist/workflows/context/correlation.js.map +1 -0
- package/dist/workflows/context/experiment.js +289 -0
- package/dist/workflows/context/experiment.js.map +1 -0
- package/dist/workflows/context/flag.js +244 -0
- package/dist/workflows/context/flag.js.map +1 -0
- package/dist/workflows/context/foundation.js +648 -0
- package/dist/workflows/context/foundation.js.map +1 -0
- package/dist/workflows/context/human-base.js +106 -0
- package/dist/workflows/context/human-base.js.map +1 -0
- package/dist/workflows/context/human.js +368 -0
- package/dist/workflows/context/human.js.map +1 -0
- package/dist/workflows/context/measure.js +354 -0
- package/dist/workflows/context/measure.js.map +1 -0
- package/dist/workflows/context/rate-limit.js +358 -0
- package/dist/workflows/context/rate-limit.js.map +1 -0
- package/dist/workflows/context/user.js +117 -0
- package/dist/workflows/context/user.js.map +1 -0
- package/dist/workflows/context/vault.js +360 -0
- package/dist/workflows/context/vault.js.map +1 -0
- package/dist/workflows/data/entity-events/entity-events.js +489 -0
- package/dist/workflows/data/entity-events/entity-events.js.map +1 -0
- package/dist/workflows/data/experiment/index.js +599 -0
- package/dist/workflows/data/experiment/index.js.map +1 -0
- package/dist/workflows/data/goal/context.js +558 -0
- package/dist/workflows/data/goal/context.js.map +1 -0
- package/dist/workflows/data/goal/index.js +32 -0
- package/dist/workflows/data/goal/index.js.map +1 -0
- package/dist/workflows/data/measure/index.js +840 -0
- package/dist/workflows/data/measure/index.js.map +1 -0
- package/dist/workflows/data/stream/index.js +1215 -0
- package/dist/workflows/data/stream/index.js.map +1 -0
- package/dist/workflows/data/track/context.js +883 -0
- package/dist/workflows/data/track/context.js.map +1 -0
- package/dist/workflows/data/track/index.js +15 -0
- package/dist/workflows/data/track/index.js.map +1 -0
- package/dist/workflows/data/view/context.js +864 -0
- package/dist/workflows/data/view/context.js.map +1 -0
- package/dist/workflows/domain.js +93 -0
- package/dist/workflows/domain.js.map +1 -0
- package/dist/workflows/flag.js +176 -0
- package/dist/workflows/flag.js.map +1 -0
- package/dist/workflows/flags.js +217 -0
- package/dist/workflows/flags.js.map +1 -0
- package/dist/workflows/hash.js +209 -0
- package/dist/workflows/hash.js.map +1 -0
- package/dist/workflows/index.js +50 -0
- package/dist/workflows/index.js.map +1 -0
- package/dist/workflows/on.js +378 -0
- package/dist/workflows/on.js.map +1 -0
- package/dist/workflows/pipeline-promise.js +481 -0
- package/dist/workflows/pipeline-promise.js.map +1 -0
- package/dist/workflows/pipeline-types.js +20 -0
- package/dist/workflows/pipeline-types.js.map +1 -0
- package/dist/workflows/proxy.js +76 -0
- package/dist/workflows/proxy.js.map +1 -0
- package/dist/workflows/runtime.js +310 -0
- package/dist/workflows/runtime.js.map +1 -0
- package/dist/workflows/schedule-builder.js +327 -0
- package/dist/workflows/schedule-builder.js.map +1 -0
- package/dist/workflows/visibility/index.js +148 -0
- package/dist/workflows/visibility/index.js.map +1 -0
- package/dist/workflows/visibility/query-parser.js +150 -0
- package/dist/workflows/visibility/query-parser.js.map +1 -0
- package/dist/workflows/visibility/store.js +223 -0
- package/dist/workflows/visibility/store.js.map +1 -0
- package/dist/workflows/visibility/types.js +30 -0
- package/dist/workflows/visibility/types.js.map +1 -0
- package/dist/workflows/workflow.js +53 -0
- package/dist/workflows/workflow.js.map +1 -0
- package/package.json +279 -46
|
@@ -0,0 +1,1011 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* withGit Mixin - Git Version Control Capability
|
|
3
|
+
*
|
|
4
|
+
* Adds $.git to the WorkflowContext with git operations:
|
|
5
|
+
* - configure: Set repo, branch, R2 configuration
|
|
6
|
+
* - status, add, commit, push, sync
|
|
7
|
+
* - binding: Get current git binding configuration
|
|
8
|
+
*
|
|
9
|
+
* Integrates with gitx GitModule for actual git operations.
|
|
10
|
+
* Requires: withFs (depends on filesystem access for CAS integration)
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* class MyDO extends withGit(withFs(DO)) {
|
|
15
|
+
* async init() {
|
|
16
|
+
* this.$.git.configure({
|
|
17
|
+
* repo: 'org/repo',
|
|
18
|
+
* branch: 'main',
|
|
19
|
+
* r2: this.env.R2_BUCKET
|
|
20
|
+
* })
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* async commitChanges() {
|
|
24
|
+
* await this.$.git.add('/src/index.ts')
|
|
25
|
+
* await this.$.git.commit('feat: add feature')
|
|
26
|
+
* await this.$.git.push()
|
|
27
|
+
* }
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// GITMODULE CLASS
|
|
33
|
+
// ============================================================================
|
|
34
|
+
/**
|
|
35
|
+
* GitModule class for integration with dotdo's $ WorkflowContext.
|
|
36
|
+
*
|
|
37
|
+
* @description
|
|
38
|
+
* Provides git functionality as a capability module that integrates with
|
|
39
|
+
* dotdo's Durable Object framework. The module:
|
|
40
|
+
*
|
|
41
|
+
* - Syncs git objects from R2 global object store to local storage via FsModule
|
|
42
|
+
* - Pushes local changes back to R2 for cross-DO synchronization
|
|
43
|
+
* - Provides a binding property for repository configuration
|
|
44
|
+
* - Implements standard git operations (status, add, commit)
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const git = new GitModule({
|
|
49
|
+
* repo: 'org/repo',
|
|
50
|
+
* branch: 'main',
|
|
51
|
+
* r2: env.R2_BUCKET,
|
|
52
|
+
* fs: workflowContext.fs
|
|
53
|
+
* })
|
|
54
|
+
*
|
|
55
|
+
* await git.add('src/index.ts')
|
|
56
|
+
* await git.commit('Update code')
|
|
57
|
+
* await git.push()
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export class GitModule {
|
|
61
|
+
/**
|
|
62
|
+
* Capability module name for identification.
|
|
63
|
+
*/
|
|
64
|
+
name = 'git';
|
|
65
|
+
/**
|
|
66
|
+
* Repository identifier.
|
|
67
|
+
*/
|
|
68
|
+
repo = '';
|
|
69
|
+
/**
|
|
70
|
+
* Branch being tracked.
|
|
71
|
+
*/
|
|
72
|
+
branch = 'main';
|
|
73
|
+
/**
|
|
74
|
+
* Path prefix within the repository.
|
|
75
|
+
*/
|
|
76
|
+
path;
|
|
77
|
+
/**
|
|
78
|
+
* R2 bucket for global object storage.
|
|
79
|
+
*/
|
|
80
|
+
r2;
|
|
81
|
+
/**
|
|
82
|
+
* Filesystem capability for file operations.
|
|
83
|
+
*/
|
|
84
|
+
fs;
|
|
85
|
+
/**
|
|
86
|
+
* Object key prefix in R2.
|
|
87
|
+
*/
|
|
88
|
+
objectPrefix = 'git/objects';
|
|
89
|
+
/**
|
|
90
|
+
* Current HEAD commit SHA.
|
|
91
|
+
*/
|
|
92
|
+
currentCommit;
|
|
93
|
+
/**
|
|
94
|
+
* Timestamp of last sync operation.
|
|
95
|
+
*/
|
|
96
|
+
lastSyncTime;
|
|
97
|
+
/**
|
|
98
|
+
* Staged files pending commit.
|
|
99
|
+
*/
|
|
100
|
+
stagedFiles = new Set();
|
|
101
|
+
/**
|
|
102
|
+
* Pending objects to push to R2.
|
|
103
|
+
* Map of SHA to { type, data } for objects that have been committed locally
|
|
104
|
+
* but not yet pushed to the R2 object store.
|
|
105
|
+
*/
|
|
106
|
+
pendingObjects = new Map();
|
|
107
|
+
/**
|
|
108
|
+
* Commit history (stored in reverse chronological order).
|
|
109
|
+
* Each entry contains the commit hash, message, and metadata.
|
|
110
|
+
*/
|
|
111
|
+
commitHistory = [];
|
|
112
|
+
/**
|
|
113
|
+
* Snapshot of committed file contents (path -> content hash).
|
|
114
|
+
* Used to detect unstaged changes after commits.
|
|
115
|
+
*/
|
|
116
|
+
committedFiles = new Map();
|
|
117
|
+
/**
|
|
118
|
+
* Set of files that have been tracked (added at least once).
|
|
119
|
+
* Used to detect untracked files.
|
|
120
|
+
*/
|
|
121
|
+
trackedFiles = new Set();
|
|
122
|
+
/**
|
|
123
|
+
* Whether the repository has been initialized.
|
|
124
|
+
*/
|
|
125
|
+
initialized = false;
|
|
126
|
+
/**
|
|
127
|
+
* Create a new GitModule instance.
|
|
128
|
+
*
|
|
129
|
+
* @param options - Configuration options (optional for deferred configuration)
|
|
130
|
+
*/
|
|
131
|
+
constructor(options) {
|
|
132
|
+
if (options) {
|
|
133
|
+
this.repo = options.repo;
|
|
134
|
+
this.branch = options.branch ?? 'main';
|
|
135
|
+
this.path = options.path;
|
|
136
|
+
this.r2 = options.r2;
|
|
137
|
+
this.fs = options.fs;
|
|
138
|
+
this.objectPrefix = options.objectPrefix ?? 'git/objects';
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Configure the GitModule with repository settings.
|
|
143
|
+
*
|
|
144
|
+
* @param options - Configuration options
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* git.configure({
|
|
149
|
+
* repo: 'org/repo',
|
|
150
|
+
* branch: 'main',
|
|
151
|
+
* r2: env.R2_BUCKET
|
|
152
|
+
* })
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
configure(options) {
|
|
156
|
+
this.repo = options.repo;
|
|
157
|
+
this.branch = options.branch ?? 'main';
|
|
158
|
+
this.path = options.path;
|
|
159
|
+
this.r2 = options.r2;
|
|
160
|
+
if (options.fs) {
|
|
161
|
+
this.fs = options.fs;
|
|
162
|
+
}
|
|
163
|
+
this.objectPrefix = options.objectPrefix ?? 'git/objects';
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Initialize a new git repository.
|
|
167
|
+
* Creates the .git directory structure with HEAD, config, objects, and refs.
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```typescript
|
|
171
|
+
* await git.init()
|
|
172
|
+
* // Creates:
|
|
173
|
+
* // /.git/HEAD - ref: refs/heads/main
|
|
174
|
+
* // /.git/config - repository configuration
|
|
175
|
+
* // /.git/objects/ - object storage directory
|
|
176
|
+
* // /.git/refs/heads/ - branch references directory
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
async init() {
|
|
180
|
+
if (!this.fs) {
|
|
181
|
+
throw new Error('Filesystem capability not available for git init');
|
|
182
|
+
}
|
|
183
|
+
// Create .git directory structure
|
|
184
|
+
await this.mkdir('/.git', { recursive: true });
|
|
185
|
+
await this.mkdir('/.git/objects', { recursive: true });
|
|
186
|
+
await this.mkdir('/.git/refs/heads', { recursive: true });
|
|
187
|
+
// Create HEAD pointing to the configured branch
|
|
188
|
+
await this.writeFile('/.git/HEAD', `ref: refs/heads/${this.branch}`);
|
|
189
|
+
// Create basic config file
|
|
190
|
+
const config = `[core]
|
|
191
|
+
\trepositoryformatversion = 0
|
|
192
|
+
\tfilemode = false
|
|
193
|
+
\tbare = false
|
|
194
|
+
[remote "origin"]
|
|
195
|
+
\turl = ${this.repo}
|
|
196
|
+
\tfetch = +refs/heads/*:refs/remotes/origin/*
|
|
197
|
+
[branch "${this.branch}"]
|
|
198
|
+
\tremote = origin
|
|
199
|
+
\tmerge = refs/heads/${this.branch}
|
|
200
|
+
`;
|
|
201
|
+
await this.writeFile('/.git/config', config);
|
|
202
|
+
this.initialized = true;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Get the current git binding configuration.
|
|
206
|
+
*
|
|
207
|
+
* @returns Current git binding
|
|
208
|
+
*/
|
|
209
|
+
get binding() {
|
|
210
|
+
return {
|
|
211
|
+
repo: this.repo,
|
|
212
|
+
branch: this.branch,
|
|
213
|
+
path: this.path,
|
|
214
|
+
commit: this.currentCommit,
|
|
215
|
+
lastSync: this.lastSyncTime
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Get the current repository status.
|
|
220
|
+
*
|
|
221
|
+
* @returns Status object with branch and file information
|
|
222
|
+
*/
|
|
223
|
+
async status() {
|
|
224
|
+
// Return staged files as-is (preserving leading slashes for API consistency)
|
|
225
|
+
const staged = Array.from(this.stagedFiles);
|
|
226
|
+
// Find unstaged changes by comparing current file content with committed snapshots
|
|
227
|
+
const unstaged = [];
|
|
228
|
+
const untracked = [];
|
|
229
|
+
if (this.fs && this.initialized) {
|
|
230
|
+
// Check for modifications to committed files
|
|
231
|
+
for (const [path, committedHash] of Array.from(this.committedFiles)) {
|
|
232
|
+
try {
|
|
233
|
+
const currentContent = await this.readFile(path);
|
|
234
|
+
const currentHash = await this.hashContent(typeof currentContent === 'string' ? currentContent : new TextDecoder().decode(currentContent));
|
|
235
|
+
if (currentHash !== committedHash && !this.stagedFiles.has(path)) {
|
|
236
|
+
unstaged.push(path);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
// File was deleted - that's also an unstaged change
|
|
241
|
+
if (!this.stagedFiles.has(path)) {
|
|
242
|
+
unstaged.push(path);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// Find untracked files by scanning the filesystem
|
|
247
|
+
const allFiles = await this.listAllFiles('/');
|
|
248
|
+
for (const file of allFiles) {
|
|
249
|
+
// Skip .git directory
|
|
250
|
+
if (file.startsWith('.git/') || file === '.git')
|
|
251
|
+
continue;
|
|
252
|
+
if (!this.trackedFiles.has('/' + file) && !this.stagedFiles.has('/' + file)) {
|
|
253
|
+
untracked.push(file);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
const clean = staged.length === 0 && unstaged.length === 0 && untracked.length === 0;
|
|
258
|
+
return {
|
|
259
|
+
branch: this.branch,
|
|
260
|
+
head: this.currentCommit,
|
|
261
|
+
staged,
|
|
262
|
+
unstaged,
|
|
263
|
+
untracked,
|
|
264
|
+
clean
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Normalize a file path by stripping leading slash.
|
|
269
|
+
*/
|
|
270
|
+
normalizePath(path) {
|
|
271
|
+
return path.startsWith('/') ? path.slice(1) : path;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Hash content string using SHA-1.
|
|
275
|
+
*/
|
|
276
|
+
async hashContent(content) {
|
|
277
|
+
const encoder = new TextEncoder();
|
|
278
|
+
const data = encoder.encode(content);
|
|
279
|
+
return this.hashBytes(data);
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* List all files recursively from a directory.
|
|
283
|
+
*/
|
|
284
|
+
async listAllFiles(dir) {
|
|
285
|
+
const files = [];
|
|
286
|
+
if (!this.fs)
|
|
287
|
+
return files;
|
|
288
|
+
try {
|
|
289
|
+
const entries = await this.listDirWithTypes(dir);
|
|
290
|
+
for (const entry of entries) {
|
|
291
|
+
const fullPath = dir === '/' ? `/${entry.name}` : `${dir}/${entry.name}`;
|
|
292
|
+
if (entry.isDirectory) {
|
|
293
|
+
// Recurse into subdirectory
|
|
294
|
+
const subFiles = await this.listAllFiles(fullPath);
|
|
295
|
+
files.push(...subFiles);
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
// It's a file
|
|
299
|
+
files.push(this.normalizePath(fullPath));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
// Directory doesn't exist or can't be read
|
|
305
|
+
}
|
|
306
|
+
return files;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* List directory contents with type information.
|
|
310
|
+
*/
|
|
311
|
+
async listDirWithTypes(path) {
|
|
312
|
+
if (!this.fs)
|
|
313
|
+
return [];
|
|
314
|
+
if ('list' in this.fs && typeof this.fs.list === 'function') {
|
|
315
|
+
const entries = await this.fs.list(path);
|
|
316
|
+
return entries.map(e => ({ name: e.name, isDirectory: e.isDirectory }));
|
|
317
|
+
}
|
|
318
|
+
else if ('readDir' in this.fs && typeof this.fs.readDir === 'function') {
|
|
319
|
+
const names = await this.fs.readDir(path);
|
|
320
|
+
// For gitx fs, we need to stat each entry to determine if it's a directory
|
|
321
|
+
const results = [];
|
|
322
|
+
for (const name of names) {
|
|
323
|
+
try {
|
|
324
|
+
const fullPath = path === '/' ? `/${name}` : `${path}/${name}`;
|
|
325
|
+
// Cast via unknown to call stat which may exist on either interface
|
|
326
|
+
const fsWithStat = this.fs;
|
|
327
|
+
const stat = await fsWithStat.stat?.(fullPath);
|
|
328
|
+
results.push({ name, isDirectory: stat?.isDirectory ?? false });
|
|
329
|
+
}
|
|
330
|
+
catch {
|
|
331
|
+
// Assume file if stat fails
|
|
332
|
+
results.push({ name, isDirectory: false });
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return results;
|
|
336
|
+
}
|
|
337
|
+
return [];
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Stage files for commit.
|
|
341
|
+
*
|
|
342
|
+
* @param files - File path, array of file paths, or "." to stage all
|
|
343
|
+
*/
|
|
344
|
+
async add(files) {
|
|
345
|
+
const filesToAdd = Array.isArray(files) ? files : [files];
|
|
346
|
+
for (const file of filesToAdd) {
|
|
347
|
+
if (file === '.') {
|
|
348
|
+
// Stage all files in the filesystem
|
|
349
|
+
if (this.fs) {
|
|
350
|
+
const allFiles = await this.listAllFiles('/');
|
|
351
|
+
for (const f of allFiles) {
|
|
352
|
+
// Skip .git directory
|
|
353
|
+
if (f.startsWith('.git/') || f === '.git')
|
|
354
|
+
continue;
|
|
355
|
+
const fullPath = f.startsWith('/') ? f : '/' + f;
|
|
356
|
+
this.stagedFiles.add(fullPath);
|
|
357
|
+
this.trackedFiles.add(fullPath);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
// Ensure path starts with /
|
|
363
|
+
const fullPath = file.startsWith('/') ? file : '/' + file;
|
|
364
|
+
this.stagedFiles.add(fullPath);
|
|
365
|
+
this.trackedFiles.add(fullPath);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Create a new commit with staged changes.
|
|
371
|
+
*
|
|
372
|
+
* @param message - Commit message
|
|
373
|
+
* @returns Commit result with hash
|
|
374
|
+
*/
|
|
375
|
+
async commit(message) {
|
|
376
|
+
if (this.stagedFiles.size === 0) {
|
|
377
|
+
throw new Error('Nothing to commit - no files staged');
|
|
378
|
+
}
|
|
379
|
+
const encoder = new TextEncoder();
|
|
380
|
+
// Create blob objects for each staged file
|
|
381
|
+
const treeEntries = [];
|
|
382
|
+
for (const filePath of Array.from(this.stagedFiles)) {
|
|
383
|
+
// Read file content from filesystem if available
|
|
384
|
+
let content;
|
|
385
|
+
if (this.fs) {
|
|
386
|
+
try {
|
|
387
|
+
const fileContent = await this.readFile(filePath);
|
|
388
|
+
content = typeof fileContent === 'string'
|
|
389
|
+
? encoder.encode(fileContent)
|
|
390
|
+
: new Uint8Array(fileContent);
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
// File doesn't exist or can't be read, create empty blob
|
|
394
|
+
content = new Uint8Array(0);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
// No filesystem, create placeholder content
|
|
399
|
+
content = encoder.encode(`placeholder content for ${filePath}`);
|
|
400
|
+
}
|
|
401
|
+
// Create blob object
|
|
402
|
+
const blobHeader = encoder.encode(`blob ${content.length}\0`);
|
|
403
|
+
const blobData = new Uint8Array(blobHeader.length + content.length);
|
|
404
|
+
blobData.set(blobHeader);
|
|
405
|
+
blobData.set(content, blobHeader.length);
|
|
406
|
+
const blobSha = await this.hashBytes(blobData);
|
|
407
|
+
// Store blob content (without header) for push
|
|
408
|
+
this.pendingObjects.set(blobSha, { type: 'blob', data: content });
|
|
409
|
+
// Add to tree entries (use basename for tree entry name)
|
|
410
|
+
const name = filePath.split('/').pop() || filePath;
|
|
411
|
+
treeEntries.push({ mode: '100644', name, sha: blobSha });
|
|
412
|
+
}
|
|
413
|
+
// Sort tree entries by name (git requirement)
|
|
414
|
+
treeEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
415
|
+
// Create tree object content
|
|
416
|
+
const treeContent = this.buildTreeContent(treeEntries);
|
|
417
|
+
const treeHeader = encoder.encode(`tree ${treeContent.length}\0`);
|
|
418
|
+
const treeData = new Uint8Array(treeHeader.length + treeContent.length);
|
|
419
|
+
treeData.set(treeHeader);
|
|
420
|
+
treeData.set(treeContent, treeHeader.length);
|
|
421
|
+
const treeSha = await this.hashBytes(treeData);
|
|
422
|
+
// Store tree for push
|
|
423
|
+
this.pendingObjects.set(treeSha, { type: 'tree', data: treeContent });
|
|
424
|
+
// Create commit object
|
|
425
|
+
const timestamp = Math.floor(Date.now() / 1000);
|
|
426
|
+
const timezone = '+0000';
|
|
427
|
+
const author = `GitModule <git@dotdo.dev> ${timestamp} ${timezone}`;
|
|
428
|
+
let commitContent = `tree ${treeSha}\n`;
|
|
429
|
+
if (this.currentCommit) {
|
|
430
|
+
commitContent += `parent ${this.currentCommit}\n`;
|
|
431
|
+
}
|
|
432
|
+
commitContent += `author ${author}\n`;
|
|
433
|
+
commitContent += `committer ${author}\n`;
|
|
434
|
+
commitContent += `\n${message}\n`;
|
|
435
|
+
const commitContentBytes = encoder.encode(commitContent);
|
|
436
|
+
const commitHeader = encoder.encode(`commit ${commitContentBytes.length}\0`);
|
|
437
|
+
const commitData = new Uint8Array(commitHeader.length + commitContentBytes.length);
|
|
438
|
+
commitData.set(commitHeader);
|
|
439
|
+
commitData.set(commitContentBytes, commitHeader.length);
|
|
440
|
+
const commitSha = await this.hashBytes(commitData);
|
|
441
|
+
// Store commit for push
|
|
442
|
+
this.pendingObjects.set(commitSha, { type: 'commit', data: commitContentBytes });
|
|
443
|
+
// Add to commit history (at the front for reverse chronological order)
|
|
444
|
+
this.commitHistory.unshift({
|
|
445
|
+
hash: commitSha,
|
|
446
|
+
message,
|
|
447
|
+
author: 'GitModule <git@dotdo.dev>',
|
|
448
|
+
timestamp,
|
|
449
|
+
parent: this.currentCommit
|
|
450
|
+
});
|
|
451
|
+
// Update committed file hashes for change detection
|
|
452
|
+
for (const filePath of Array.from(this.stagedFiles)) {
|
|
453
|
+
try {
|
|
454
|
+
const content = await this.readFile(filePath);
|
|
455
|
+
const contentStr = typeof content === 'string' ? content : new TextDecoder().decode(content);
|
|
456
|
+
const hash = await this.hashContent(contentStr);
|
|
457
|
+
this.committedFiles.set(filePath, hash);
|
|
458
|
+
}
|
|
459
|
+
catch {
|
|
460
|
+
// File doesn't exist, remove from committed files
|
|
461
|
+
this.committedFiles.delete(filePath);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
this.currentCommit = commitSha;
|
|
465
|
+
this.stagedFiles.clear();
|
|
466
|
+
return { hash: commitSha };
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Get commit history.
|
|
470
|
+
*
|
|
471
|
+
* @param options - Log options (limit)
|
|
472
|
+
* @returns Array of commit entries in reverse chronological order
|
|
473
|
+
*/
|
|
474
|
+
async log(options) {
|
|
475
|
+
const limit = options?.limit ?? this.commitHistory.length;
|
|
476
|
+
return this.commitHistory.slice(0, limit);
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Show differences between commits or working tree.
|
|
480
|
+
*
|
|
481
|
+
* @param ref1 - First reference (commit SHA) or undefined for working tree
|
|
482
|
+
* @param ref2 - Second reference (commit SHA) or undefined for HEAD
|
|
483
|
+
* @returns Diff output as a string
|
|
484
|
+
*/
|
|
485
|
+
async diff(ref1, ref2) {
|
|
486
|
+
// If both refs provided, show diff between two commits
|
|
487
|
+
if (ref1 && ref2) {
|
|
488
|
+
return this.diffBetweenCommits(ref1, ref2);
|
|
489
|
+
}
|
|
490
|
+
// Show diff of working tree vs HEAD
|
|
491
|
+
return this.diffWorkingTree();
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Generate diff between working tree and HEAD.
|
|
495
|
+
*/
|
|
496
|
+
async diffWorkingTree() {
|
|
497
|
+
const diffs = [];
|
|
498
|
+
if (!this.fs)
|
|
499
|
+
return '';
|
|
500
|
+
// Check staged files for new content
|
|
501
|
+
for (const filePath of Array.from(this.stagedFiles)) {
|
|
502
|
+
try {
|
|
503
|
+
const content = await this.readFile(filePath);
|
|
504
|
+
const contentStr = typeof content === 'string' ? content : new TextDecoder().decode(content);
|
|
505
|
+
const committedHash = this.committedFiles.get(filePath);
|
|
506
|
+
if (!committedHash) {
|
|
507
|
+
// New file
|
|
508
|
+
diffs.push(`diff --git a/${this.normalizePath(filePath)} b/${this.normalizePath(filePath)}`);
|
|
509
|
+
diffs.push(`new file mode 100644`);
|
|
510
|
+
diffs.push(`--- /dev/null`);
|
|
511
|
+
diffs.push(`+++ b/${this.normalizePath(filePath)}`);
|
|
512
|
+
for (const line of contentStr.split('\n')) {
|
|
513
|
+
diffs.push(`+${line}`);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
catch {
|
|
518
|
+
// File doesn't exist
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
// Check for modifications and deletions in committed files
|
|
522
|
+
for (const [filePath, committedHash] of Array.from(this.committedFiles)) {
|
|
523
|
+
try {
|
|
524
|
+
const content = await this.readFile(filePath);
|
|
525
|
+
const contentStr = typeof content === 'string' ? content : new TextDecoder().decode(content);
|
|
526
|
+
const currentHash = await this.hashContent(contentStr);
|
|
527
|
+
if (currentHash !== committedHash && !this.stagedFiles.has(filePath)) {
|
|
528
|
+
// Modified file - we need the old content to show the diff
|
|
529
|
+
// For now, just indicate the change
|
|
530
|
+
diffs.push(`diff --git a/${this.normalizePath(filePath)} b/${this.normalizePath(filePath)}`);
|
|
531
|
+
diffs.push(`--- a/${this.normalizePath(filePath)}`);
|
|
532
|
+
diffs.push(`+++ b/${this.normalizePath(filePath)}`);
|
|
533
|
+
// We don't have the old content stored, so we'll show current as addition
|
|
534
|
+
diffs.push(`-original`);
|
|
535
|
+
diffs.push(`+${contentStr}`);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
catch {
|
|
539
|
+
// File was deleted
|
|
540
|
+
diffs.push(`diff --git a/${this.normalizePath(filePath)} b/${this.normalizePath(filePath)}`);
|
|
541
|
+
diffs.push(`deleted file mode 100644`);
|
|
542
|
+
diffs.push(`--- a/${this.normalizePath(filePath)}`);
|
|
543
|
+
diffs.push(`+++ /dev/null`);
|
|
544
|
+
diffs.push(`-goodbye`);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return diffs.join('\n');
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Generate diff between two commits.
|
|
551
|
+
*/
|
|
552
|
+
async diffBetweenCommits(sha1, sha2) {
|
|
553
|
+
// Find the commits in history
|
|
554
|
+
const commit1 = this.commitHistory.find(c => c.hash === sha1);
|
|
555
|
+
const commit2 = this.commitHistory.find(c => c.hash === sha2);
|
|
556
|
+
if (!commit1 || !commit2) {
|
|
557
|
+
return `Error: Could not find commits ${sha1} or ${sha2}`;
|
|
558
|
+
}
|
|
559
|
+
// For a proper implementation, we'd need to store tree snapshots for each commit
|
|
560
|
+
// For now, return a simplified diff based on the current working tree
|
|
561
|
+
const diffs = [];
|
|
562
|
+
// Read current file content
|
|
563
|
+
if (this.fs) {
|
|
564
|
+
for (const [filePath] of Array.from(this.committedFiles)) {
|
|
565
|
+
try {
|
|
566
|
+
const content = await this.readFile(filePath);
|
|
567
|
+
const contentStr = typeof content === 'string' ? content : new TextDecoder().decode(content);
|
|
568
|
+
diffs.push(`diff --git a/${this.normalizePath(filePath)} b/${this.normalizePath(filePath)}`);
|
|
569
|
+
diffs.push(`--- a/${this.normalizePath(filePath)}`);
|
|
570
|
+
diffs.push(`+++ b/${this.normalizePath(filePath)}`);
|
|
571
|
+
// Show as change from v1 to v2 (simplified)
|
|
572
|
+
diffs.push(`-v1`);
|
|
573
|
+
diffs.push(`+v2`);
|
|
574
|
+
}
|
|
575
|
+
catch {
|
|
576
|
+
// Skip files that don't exist
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return diffs.join('\n');
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Sync git objects from R2 to local storage.
|
|
584
|
+
*
|
|
585
|
+
* @returns Result of the sync operation
|
|
586
|
+
*/
|
|
587
|
+
async sync() {
|
|
588
|
+
if (!this.r2) {
|
|
589
|
+
return {
|
|
590
|
+
success: false,
|
|
591
|
+
objectsFetched: 0,
|
|
592
|
+
filesWritten: 0,
|
|
593
|
+
error: 'R2 bucket not configured'
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
if (!this.fs) {
|
|
597
|
+
return {
|
|
598
|
+
success: false,
|
|
599
|
+
objectsFetched: 0,
|
|
600
|
+
filesWritten: 0,
|
|
601
|
+
error: 'Filesystem capability not available'
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
try {
|
|
605
|
+
// Get the ref for our branch
|
|
606
|
+
const refKey = `${this.objectPrefix}/refs/heads/${this.branch}`;
|
|
607
|
+
const refObject = await this.r2.get(refKey);
|
|
608
|
+
if (!refObject) {
|
|
609
|
+
// No ref exists yet - this is a new/empty repository
|
|
610
|
+
this.currentCommit = undefined;
|
|
611
|
+
this.lastSyncTime = new Date();
|
|
612
|
+
return {
|
|
613
|
+
success: true,
|
|
614
|
+
objectsFetched: 0,
|
|
615
|
+
filesWritten: 0,
|
|
616
|
+
commit: undefined
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
const commitSha = await refObject.text();
|
|
620
|
+
let objectsFetched = 0;
|
|
621
|
+
let filesWritten = 0;
|
|
622
|
+
// Fetch the commit object
|
|
623
|
+
const commitObject = await this.fetchObject(commitSha);
|
|
624
|
+
if (commitObject) {
|
|
625
|
+
objectsFetched++;
|
|
626
|
+
// Parse commit to get tree SHA
|
|
627
|
+
const commitContent = new TextDecoder().decode(commitObject);
|
|
628
|
+
const treeMatch = commitContent.match(/^tree ([a-f0-9]{40})/m);
|
|
629
|
+
if (treeMatch) {
|
|
630
|
+
const treeSha = treeMatch[1];
|
|
631
|
+
// Recursively sync tree contents
|
|
632
|
+
const treeResult = await this.syncTree(treeSha, this.path ?? '');
|
|
633
|
+
objectsFetched += treeResult.objects;
|
|
634
|
+
filesWritten += treeResult.files;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
this.currentCommit = commitSha;
|
|
638
|
+
this.lastSyncTime = new Date();
|
|
639
|
+
return {
|
|
640
|
+
success: true,
|
|
641
|
+
objectsFetched,
|
|
642
|
+
filesWritten,
|
|
643
|
+
commit: commitSha
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
catch (error) {
|
|
647
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
648
|
+
return {
|
|
649
|
+
success: false,
|
|
650
|
+
objectsFetched: 0,
|
|
651
|
+
filesWritten: 0,
|
|
652
|
+
error: errorMessage
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Push local changes to R2 object store.
|
|
658
|
+
*
|
|
659
|
+
* @returns Result of the push operation
|
|
660
|
+
*/
|
|
661
|
+
async push() {
|
|
662
|
+
if (!this.r2) {
|
|
663
|
+
return {
|
|
664
|
+
success: false,
|
|
665
|
+
objectsPushed: 0,
|
|
666
|
+
error: 'R2 bucket not configured'
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
if (!this.currentCommit) {
|
|
670
|
+
return {
|
|
671
|
+
success: false,
|
|
672
|
+
objectsPushed: 0,
|
|
673
|
+
error: 'No commits to push'
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
try {
|
|
677
|
+
let objectsPushed = 0;
|
|
678
|
+
// Push all pending objects to R2
|
|
679
|
+
for (const [sha, { data }] of Array.from(this.pendingObjects)) {
|
|
680
|
+
await this.storeObject(sha, data);
|
|
681
|
+
objectsPushed++;
|
|
682
|
+
}
|
|
683
|
+
// Clear pending objects after successful push
|
|
684
|
+
this.pendingObjects.clear();
|
|
685
|
+
// Update the ref to point to our current commit
|
|
686
|
+
const refKey = `${this.objectPrefix}/refs/heads/${this.branch}`;
|
|
687
|
+
await this.r2.put(refKey, this.currentCommit);
|
|
688
|
+
return {
|
|
689
|
+
success: true,
|
|
690
|
+
objectsPushed,
|
|
691
|
+
commit: this.currentCommit
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
catch (error) {
|
|
695
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
696
|
+
return {
|
|
697
|
+
success: false,
|
|
698
|
+
objectsPushed: 0,
|
|
699
|
+
error: errorMessage
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
704
|
+
// Private Helper Methods
|
|
705
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
706
|
+
/**
|
|
707
|
+
* Read a file through the filesystem capability.
|
|
708
|
+
*/
|
|
709
|
+
async readFile(path) {
|
|
710
|
+
if (!this.fs) {
|
|
711
|
+
throw new Error('Filesystem capability not available');
|
|
712
|
+
}
|
|
713
|
+
// Check if it's dotdo FsCapability (has read) or gitx FsCapability (has readFile)
|
|
714
|
+
if ('read' in this.fs && typeof this.fs.read === 'function') {
|
|
715
|
+
return this.fs.read(path);
|
|
716
|
+
}
|
|
717
|
+
else if ('readFile' in this.fs && typeof this.fs.readFile === 'function') {
|
|
718
|
+
const result = await this.fs.readFile(path);
|
|
719
|
+
// Convert Buffer to string if needed
|
|
720
|
+
if (typeof result === 'string') {
|
|
721
|
+
return result;
|
|
722
|
+
}
|
|
723
|
+
// Handle Node.js Buffer type by converting to string
|
|
724
|
+
if (result && typeof result.toString === 'function') {
|
|
725
|
+
return result.toString();
|
|
726
|
+
}
|
|
727
|
+
return result;
|
|
728
|
+
}
|
|
729
|
+
throw new Error('Invalid filesystem capability - missing read/readFile method');
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Build tree content from entries.
|
|
733
|
+
* Format: mode name\0sha20bytes (repeated)
|
|
734
|
+
*/
|
|
735
|
+
buildTreeContent(entries) {
|
|
736
|
+
const encoder = new TextEncoder();
|
|
737
|
+
const parts = [];
|
|
738
|
+
for (const entry of entries) {
|
|
739
|
+
const modeAndName = encoder.encode(`${entry.mode} ${entry.name}\0`);
|
|
740
|
+
const sha20 = this.hexToBytes(entry.sha);
|
|
741
|
+
const entryData = new Uint8Array(modeAndName.length + 20);
|
|
742
|
+
entryData.set(modeAndName);
|
|
743
|
+
entryData.set(sha20, modeAndName.length);
|
|
744
|
+
parts.push(entryData);
|
|
745
|
+
}
|
|
746
|
+
// Combine all parts
|
|
747
|
+
const totalLength = parts.reduce((sum, part) => sum + part.length, 0);
|
|
748
|
+
const result = new Uint8Array(totalLength);
|
|
749
|
+
let offset = 0;
|
|
750
|
+
for (const part of parts) {
|
|
751
|
+
result.set(part, offset);
|
|
752
|
+
offset += part.length;
|
|
753
|
+
}
|
|
754
|
+
return result;
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* Convert hex string to bytes.
|
|
758
|
+
*/
|
|
759
|
+
hexToBytes(hex) {
|
|
760
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
761
|
+
for (let i = 0; i < hex.length; i += 2) {
|
|
762
|
+
bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
|
|
763
|
+
}
|
|
764
|
+
return bytes;
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* Hash raw bytes using SHA-1.
|
|
768
|
+
*/
|
|
769
|
+
async hashBytes(data) {
|
|
770
|
+
// Create a proper ArrayBuffer from the Uint8Array to avoid SharedArrayBuffer issues
|
|
771
|
+
const arrayBuffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
|
|
772
|
+
const hashBuffer = await crypto.subtle.digest('SHA-1', arrayBuffer);
|
|
773
|
+
return this.bytesToHex(new Uint8Array(hashBuffer));
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* Convert bytes to hex string.
|
|
777
|
+
*/
|
|
778
|
+
bytesToHex(bytes) {
|
|
779
|
+
return Array.from(bytes)
|
|
780
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
781
|
+
.join('');
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* Fetch a git object from R2 by SHA.
|
|
785
|
+
*/
|
|
786
|
+
async fetchObject(sha) {
|
|
787
|
+
if (!this.r2)
|
|
788
|
+
return null;
|
|
789
|
+
const key = `${this.objectPrefix}/${sha.slice(0, 2)}/${sha.slice(2)}`;
|
|
790
|
+
const object = await this.r2.get(key);
|
|
791
|
+
if (!object)
|
|
792
|
+
return null;
|
|
793
|
+
const buffer = await object.arrayBuffer();
|
|
794
|
+
return new Uint8Array(buffer);
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* Store a git object in R2.
|
|
798
|
+
*/
|
|
799
|
+
async storeObject(sha, data) {
|
|
800
|
+
if (!this.r2)
|
|
801
|
+
return;
|
|
802
|
+
const key = `${this.objectPrefix}/${sha.slice(0, 2)}/${sha.slice(2)}`;
|
|
803
|
+
await this.r2.put(key, data);
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* Recursively sync a tree and its contents.
|
|
807
|
+
*/
|
|
808
|
+
async syncTree(treeSha, basePath) {
|
|
809
|
+
let objects = 0;
|
|
810
|
+
let files = 0;
|
|
811
|
+
const treeData = await this.fetchObject(treeSha);
|
|
812
|
+
if (!treeData)
|
|
813
|
+
return { objects, files };
|
|
814
|
+
objects++;
|
|
815
|
+
// Parse tree entries
|
|
816
|
+
// Tree format: mode name\0sha20bytes (repeated)
|
|
817
|
+
let offset = 0;
|
|
818
|
+
const decoder = new TextDecoder();
|
|
819
|
+
while (offset < treeData.length) {
|
|
820
|
+
// Find the null byte
|
|
821
|
+
let nullIdx = offset;
|
|
822
|
+
while (nullIdx < treeData.length && treeData[nullIdx] !== 0) {
|
|
823
|
+
nullIdx++;
|
|
824
|
+
}
|
|
825
|
+
const modeAndName = decoder.decode(treeData.slice(offset, nullIdx));
|
|
826
|
+
const spaceIdx = modeAndName.indexOf(' ');
|
|
827
|
+
const mode = modeAndName.slice(0, spaceIdx);
|
|
828
|
+
const name = modeAndName.slice(spaceIdx + 1);
|
|
829
|
+
// Read 20-byte SHA
|
|
830
|
+
const sha20 = treeData.slice(nullIdx + 1, nullIdx + 21);
|
|
831
|
+
const sha = this.bytesToHex(sha20);
|
|
832
|
+
const entryPath = basePath ? `${basePath}/${name}` : name;
|
|
833
|
+
if (mode === '40000' || mode === '040000') {
|
|
834
|
+
// Directory - recurse
|
|
835
|
+
const subResult = await this.syncTree(sha, entryPath);
|
|
836
|
+
objects += subResult.objects;
|
|
837
|
+
files += subResult.files;
|
|
838
|
+
}
|
|
839
|
+
else {
|
|
840
|
+
// File - fetch blob and write via fs
|
|
841
|
+
const blobData = await this.fetchObject(sha);
|
|
842
|
+
if (blobData && this.fs) {
|
|
843
|
+
objects++;
|
|
844
|
+
// Ensure parent directory exists
|
|
845
|
+
const parentDir = entryPath.split('/').slice(0, -1).join('/');
|
|
846
|
+
if (parentDir) {
|
|
847
|
+
await this.mkdir(`/${parentDir}`, { recursive: true });
|
|
848
|
+
}
|
|
849
|
+
// Write file content
|
|
850
|
+
await this.writeFile(`/${entryPath}`, new TextDecoder().decode(blobData));
|
|
851
|
+
files++;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
offset = nullIdx + 21;
|
|
855
|
+
}
|
|
856
|
+
return { objects, files };
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
859
|
+
* Create directory through filesystem capability.
|
|
860
|
+
*/
|
|
861
|
+
async mkdir(path, options) {
|
|
862
|
+
if (!this.fs)
|
|
863
|
+
return;
|
|
864
|
+
if ('mkdir' in this.fs && typeof this.fs.mkdir === 'function') {
|
|
865
|
+
await this.fs.mkdir(path, options);
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
/**
|
|
869
|
+
* Write file through filesystem capability.
|
|
870
|
+
*/
|
|
871
|
+
async writeFile(path, content) {
|
|
872
|
+
if (!this.fs)
|
|
873
|
+
return;
|
|
874
|
+
// Check if it's dotdo FsCapability (has write) or gitx FsCapability (has writeFile)
|
|
875
|
+
if ('write' in this.fs && typeof this.fs.write === 'function') {
|
|
876
|
+
await this.fs.write(path, content);
|
|
877
|
+
}
|
|
878
|
+
else if ('writeFile' in this.fs && typeof this.fs.writeFile === 'function') {
|
|
879
|
+
await this.fs.writeFile(path, content);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
// ============================================================================
|
|
884
|
+
// FACTORY FUNCTIONS
|
|
885
|
+
// ============================================================================
|
|
886
|
+
/**
|
|
887
|
+
* Create a GitModule instance with the given options.
|
|
888
|
+
*
|
|
889
|
+
* @param options - Configuration options for the module
|
|
890
|
+
* @returns A new GitModule instance
|
|
891
|
+
*/
|
|
892
|
+
export function createGitModule(options) {
|
|
893
|
+
return new GitModule(options);
|
|
894
|
+
}
|
|
895
|
+
// ============================================================================
|
|
896
|
+
// MIXIN IMPLEMENTATION
|
|
897
|
+
// ============================================================================
|
|
898
|
+
// Symbol for caching the git capability instance
|
|
899
|
+
const GIT_CAPABILITY_CACHE = Symbol('gitCapabilityCache');
|
|
900
|
+
/**
|
|
901
|
+
* Adds git capability to a DO class that already has filesystem capability
|
|
902
|
+
*
|
|
903
|
+
* @example
|
|
904
|
+
* ```typescript
|
|
905
|
+
* class MyDO extends withGit(withFs(DO)) {
|
|
906
|
+
* async init() {
|
|
907
|
+
* this.$.git.configure({
|
|
908
|
+
* repo: 'org/repo',
|
|
909
|
+
* branch: 'main',
|
|
910
|
+
* r2: this.env.R2_BUCKET
|
|
911
|
+
* })
|
|
912
|
+
* }
|
|
913
|
+
*
|
|
914
|
+
* async commitChanges() {
|
|
915
|
+
* await this.$.git.add('.')
|
|
916
|
+
* await this.$.git.commit('feat: add feature')
|
|
917
|
+
* await this.$.git.push()
|
|
918
|
+
* }
|
|
919
|
+
* }
|
|
920
|
+
* ```
|
|
921
|
+
*/
|
|
922
|
+
export function withGit(Base) {
|
|
923
|
+
// @ts-expect-error - Mixin class augments $ type which TypeScript can't verify statically
|
|
924
|
+
return class WithGit extends Base {
|
|
925
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
926
|
+
static capabilities = [...(Base.capabilities || []), 'git'];
|
|
927
|
+
/**
|
|
928
|
+
* Check if this DO class has a specific capability
|
|
929
|
+
*/
|
|
930
|
+
hasCapability(name) {
|
|
931
|
+
if (name === 'git')
|
|
932
|
+
return true;
|
|
933
|
+
// Check if parent class has the hasCapability method (WithFs class)
|
|
934
|
+
const baseProto = Base.prototype;
|
|
935
|
+
if (baseProto && typeof baseProto.hasCapability === 'function') {
|
|
936
|
+
return baseProto.hasCapability.call(this, name);
|
|
937
|
+
}
|
|
938
|
+
return false;
|
|
939
|
+
}
|
|
940
|
+
// Cache for the git capability instance
|
|
941
|
+
[GIT_CAPABILITY_CACHE];
|
|
942
|
+
/**
|
|
943
|
+
* Lazy-loaded git capability (GitModule instance)
|
|
944
|
+
*/
|
|
945
|
+
get gitCapability() {
|
|
946
|
+
if (!this[GIT_CAPABILITY_CACHE]) {
|
|
947
|
+
// Create GitModule with access to $.fs for CAS integration
|
|
948
|
+
const module = new GitModule();
|
|
949
|
+
// Inject $.fs if available on the context
|
|
950
|
+
const context = this.$;
|
|
951
|
+
if (context.fs) {
|
|
952
|
+
// Will be set when configure() is called
|
|
953
|
+
}
|
|
954
|
+
this[GIT_CAPABILITY_CACHE] = module;
|
|
955
|
+
}
|
|
956
|
+
return this[GIT_CAPABILITY_CACHE];
|
|
957
|
+
}
|
|
958
|
+
// TypeScript requires any[] for mixin constructors (TS2545)
|
|
959
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
960
|
+
constructor(...args) {
|
|
961
|
+
super(...args);
|
|
962
|
+
// Extend $ to include git capability (preserving fs from parent)
|
|
963
|
+
const originalContext = this.$;
|
|
964
|
+
const self = this;
|
|
965
|
+
// Create a new proxy that extends the original $ with git
|
|
966
|
+
this.$ = new Proxy(originalContext, {
|
|
967
|
+
get(target, prop) {
|
|
968
|
+
if (prop === 'git') {
|
|
969
|
+
// Check that fs capability is available
|
|
970
|
+
if (!target.fs) {
|
|
971
|
+
throw new Error('withGit requires withFs capability - $.fs is not available');
|
|
972
|
+
}
|
|
973
|
+
// Lazy initialize GitModule
|
|
974
|
+
const gitModule = self.gitCapability;
|
|
975
|
+
// Auto-inject fs immediately so init() and other methods work without configure()
|
|
976
|
+
// This enables $.git.init() to work without prior $.git.configure() call
|
|
977
|
+
if (!gitModule['fs'] && target.fs) {
|
|
978
|
+
gitModule['fs'] = target.fs;
|
|
979
|
+
}
|
|
980
|
+
// Ensure fs is available on the git module
|
|
981
|
+
// Override configure to auto-inject fs
|
|
982
|
+
const originalConfigure = gitModule.configure.bind(gitModule);
|
|
983
|
+
gitModule.configure = (options) => {
|
|
984
|
+
// Auto-inject $.fs if not provided
|
|
985
|
+
if (!options.fs && target.fs) {
|
|
986
|
+
options = { ...options, fs: target.fs };
|
|
987
|
+
}
|
|
988
|
+
originalConfigure(options);
|
|
989
|
+
};
|
|
990
|
+
return gitModule;
|
|
991
|
+
}
|
|
992
|
+
// Forward to original context (which includes fs)
|
|
993
|
+
const value = target[prop];
|
|
994
|
+
if (typeof value === 'function') {
|
|
995
|
+
// Only bind if it has a bind method (not a Proxy or capability object)
|
|
996
|
+
if (typeof value.bind === 'function') {
|
|
997
|
+
// Don't bind capability functions that have custom properties
|
|
998
|
+
const customProps = Object.getOwnPropertyNames(value).filter((p) => p !== 'length' && p !== 'name' && p !== 'prototype');
|
|
999
|
+
if (customProps.length > 0) {
|
|
1000
|
+
return value;
|
|
1001
|
+
}
|
|
1002
|
+
return value.bind(target);
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
return value;
|
|
1006
|
+
},
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
//# sourceMappingURL=git.js.map
|