Skip to content

Add Daytona sandbox submodule + Example app (Python playground) - #6295

Open
bradleyshep wants to merge 53 commits into
masterfrom
bradley/submodules-daytona
Open

bradleyshep wants to merge 53 commits into
masterfrom
bradley/submodules-daytona

Conversation

@bradleyshep

@bradleyshep bradleyshep commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Description of Changes

  • Add a Daytona submodule to create sandboxes, run commands, and delete sandboxes.
  • Add a Python playground with code, Run, and output.
  • Move the examples' "Built on SpacetimeDB" footer into @spacetimedb/example-ui so all the examples share one. Cron loses its "View source" link. The same commit is in Add S3 file storage submodule #6417.

Demo

daytona-playground-trimmed.mp4

API and ABI breaking changes

None. Adds a new TypeScript package API.

Rollback safety impact

n/a

Expected complexity level and risk

2/5

FYI Command logs are downloaded in full before display truncation.

Testing

Removed the static footer markup test (Core review tier). Shared authentication and server tests remain.

  • Run Cargo submodule checks: lint, types, tests, local recovery tests, and builds.
  • Check the npm package contents.
  • Install the package in a new project with SpacetimeDB 2.12 and publish it to a 2.12 server.
  • Test the live browser flow: execution, file reuse, errors, owner access, and deletion. The test sandbox was deleted.
  • Review the public API and example setup.

bradleyshep and others added 30 commits September 8, 2026 17:18
Configure fixed policies once, expose stable errors, keep installers idempotent, and support admin revocation. Remove internal sweep exports and align init naming. Verify packed consumers with the default TypeScript template.
Drop the install options, the standalone install and sweep exports, and helpers exported only for tests. runSweep and resetBuckets share one maxRows validation.
client({ handlers }) imports the SDK directly and returns the tables,
install, submit, views, and reducers. Contexts are typed against the
retry tables instead of unknown, and thrown codes come from an exported
errors object.

retryHandler no longer defines a property on the caller's type builder,
so one builder can back several handlers. The custom auth policy is
replaced by submit(), which host reducers call after their own checks.

History is written once per attempt with its final status, pruned by
removing the oldest row through the ranAt index, and served newest first
without sorting. The unused taskName and status indexes are removed,
admin rows store addedAt as a timestamp, and the task view returns the
newest tasks.
verifyStripeSignature, verifySvixSignature, and verifyGithubSignature
return { ok: true } or { ok: false, reason } with a code from the
exported errors object, so callers can tell a missing signature, a bad
or stale timestamp, an invalid Svix secret, and a mismatch apart.

Also remove the unused SHA256_INTERNAL_BLOCK_SIZE constant, make
timingSafeEqual compile under noUncheckedIndexedAccess and enable that
check, and drop allowImportingTsExtensions now that tests import
without extensions.
Limiters are configured once per scope and expose their policy and a peek read. Remove per-call limit overrides, the admin consume procedure, and the raw consume and key exports. Export isAdmin and requireAdmin for host operations. The example uses one limiter per upgrade tier, reads status through peek, and uses reactor.* codes for its own errors. Regenerate example bindings.
cron imports the SDK directly instead of receiving it as a parameter,
so tables and types come from the real SDK and the dynamic SDK casts
are gone. client({ jobs, ...options }) replaces spacetimeCron(sdk) and
createCron(jobs, opts) and returns tables, schedule, unschedule,
reconcileReducer, and publicViews. cronTable() stays the job
declaration.

cronReducer and cronProcedure infer the handler context from the host
schema, and registration fails to compile when the schema lacks
cron.tables. cron.tables is typed per job, so host code can read fire
tables without casts. Thrown codes come from an exported errors object.

Also set the unpublished package version to 0.1.0, describe Failed runs
accurately, drop decorative separators from the modules, and remove
allowImportingTsExtensions.
client({ tasks }) declares each task's argument type before schema().
retry.retryReducer(spacetimedb, handlers) registers the scheduled
reducer afterward, so every handler receives the host's reducer context
and its task's arguments with their real types, and the host schema must
include retry.tables. retryHandler is removed along with the fixture's
context cast.
Libraries that create tables, schemas, and enum builders with this package could not emit .d.ts files because the inferred types named modules outside the package exports (TS2742) or an unexported class with private members (TS4094). The types are exported by name only; runtime exports are unchanged.
cron, crypto, rate-limit, and retry build ESM JavaScript and .d.ts files
into dist with tsc (tsconfig.build.json). pnpm pack and publish apply
publishConfig, which points main, types, and exports at dist and keeps
the subpath names; files lists dist, LICENSE, and README.md. prepack
builds before copying the license. Inside the workspace the manifests
still point at src, so examples, fixture modules, and tests do not need
a build first.

Relative imports in src carry .js extensions so the emitted modules
resolve in Node as well as in bundlers. rate-limit drops
allowImportingTsExtensions like the other packages.
Scheduled procedures run in a pool of instances, so later occurrences can
execute while the recovery probe blocks and before the host is killed. The
fireCount bound counted those runs as replays. Assert on runs scheduled
before the restart and completed after the stop, and use a two-second
schedule so the pre-kill checks finish before the next occurrence.
An index scan in a transaction yields rows inserted by that transaction
first, so pruning after the insert deleted the new attempt instead of
the oldest one once history reached 1,000 rows.
bradleyshep and others added 13 commits September 30, 2026 12:53
# Description of Changes

Adds a Resend submodule for sending transactional email and tracking
delivery state in SpacetimeDB.

- Synchronous procedures for outbound Resend requests and email
operations.
- Webhook signature verification, payload validation, idempotent
ingestion, and replay.
- Private delivery state and administrative configuration.
- Package documentation, unit tests, and a dispatch example with
generated client bindings.

Builds on `bradley/submodules-core`. The package uses crypto; the
example also uses rate-limit and shared example support.

## Example screenshots

Existing example screenshots from #5823:

### Resend

![Resend
example](https://github.com/user-attachments/assets/d13860fb-e4e9-481d-88a1-8f38c6a494ce)

# API and ABI breaking changes

No existing SpacetimeDB API or ABI is changed. This adds new TypeScript
package APIs that need review before merge.

# Rollback safety impact

n/a. This adds opt-in TypeScript packages and examples; it does not
change existing server storage formats.

# Expected complexity level and risk

**2/5**

An isolated, opt-in Resend integration that does not change existing
server behavior. For applications that use it, review delivery
idempotency, webhook verification, and access to provider credentials.

# Testing

Verified locally on `bradley/submodules-email`:

- [x] Frozen-lockfile install for the root, SDK, and present submodule
workspaces.
- [x] Type checks for the added packages.
- [x] Existing test scripts for the added packages and examples.
- [x] Build scripts for the added packages and examples.
- [x] Regenerate client bindings and verify no tracked changes.
- [x] Lint and formatting checks for the added packages and examples.
- [x] Verify workspace dependencies are present in this branch.
- [ ] Review the public email API, authorization, and webhook handling.
- [ ] Run the Resend smoke test with credentials and a local SpacetimeDB
instance.

Commands used for this group:

```sh
pnpm -r -F "./spacetime-resend-ts/**" run typecheck
pnpm -r -F "./spacetime-resend-ts/**" run test
pnpm -r -F "./spacetime-resend-ts/**" run build
pnpm -r -F "./spacetime-resend-ts/**" run lint
```

The TypeScript SDK was built first. Live deployment and provider tests
were not run during split validation. Existing workspace peer-dependency
warnings remain.
Keep code, Run, and output visible. Add owner-checked command output retrieval and verify the live sandbox flow. Full HTTP response buffering remains a known, explicitly deferred platform limit.
@bradleyshep bradleyshep changed the title Add Daytona sandbox submodule and Python playground Add Daytona sandbox submodule + Example app (Python playground) Oct 14, 2026
@bradleyshep
bradleyshep marked this pull request as ready for review October 14, 2026 23:22
The SDK peer dependency was `workspace:^`, which packs as the
unpublished 2.13.0. It is now `^2.12.0`.

Declarations failed to build against 2.12: the inline list-form enums
emit a type with a private member, and the default-exported schema's
inferred type referenced SDK types 2.12 does not export. The enums are
named constants in the equivalent object form with named builder types,
and the schema's tables object is typed from its tables.

The README setup installs the package from npm with a matching SDK and
states the 2.12 minimum instead of describing repository-only use. It
links the example on GitHub and links the license text.
`npm install <pkg> spacetimedb@^2.12.0` rewrote the `2.12.*` pin that
`spacetime init` sets, which would pull a newer SDK into a project with
a 2.12 CLI and server once one is published. The README install line
now adds only the package; npm still checks the peer range.

The example README no longer calls the submodule unpublished, and
package.json gains the homepage, bugs, and keywords fields the other
submodule packages publish with.
Add mountFooter() and footer.css to the package and use them in the
cron, resend and rate-limit examples instead of copied markup and CSS.
The footer reads --example-footer-border and --example-footer-label,
so each example keeps its own colors. Cron moves to the same footer as
the others and drops its "View source" link.
Rewrite both READMEs in the sibling shape and in plain words: Install,
Integrate into an application, API, Testing, and License for the package;
Run it locally, Try it, Change the example, Configuration, Before
deploying, and Troubleshooting for the example.

Package: exports with types, a clean build, keywords and category, and a
peer range of ^2.12.0 like the others. The test module moves from
scripts/fixture to spacetimedb/ and imports the package by name.

Example: the shared footer and brand markup, a .env.example read by the
same server code as the others, build:module and build:module:fresh, and
bindings under src/module_bindings/app.
Keep the rewritten READMEs and add the submodule category next to the
npm metadata both sides added. The README example now only lets
identities in an allowed table run code, since each run spends Daytona
credits.
The example grantAccess reducer accepts any allowed caller, so the
README no longer says only the publisher can grant access.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant