Skip to content

Commit 4bea2e2

Browse files
committed
Merge branch 'component-api'
2 parents bdc0477 + a71dd93 commit 4bea2e2

33 files changed

+1003
-1049
lines changed

.github/workflows/node.js.yml renamed to .github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
npm i
3131
npm run build
3232
- name: Publish package for testing branch
33-
run: npx pkg-pr-new publish
33+
run: npx pkg-pr-new publish || echo "Have you set up pkg-pr-new for this repo?"
3434
- name: Test
3535
run: |
3636
npm run test

.prettierrc.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"trailingComma": "all",
3+
"proseWrap": "always"
4+
}

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Changelog
2+
3+
## 0.3.0
4+
5+
- Adds /test and /\_generated/component.js entrypoints
6+
- Drops commonjs support
7+
- Improves source mapping for generated files
8+
- Changes to a statically generated component API
9+
10+
## 0.2.10 alpha
11+
12+
- Component API overhaul: /test entrypoint, unifying types, dropping cjs

CONTRIBUTING.md

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,58 +2,39 @@
22

33
## Running locally
44

5-
Setup:
6-
75
```sh
86
npm i
9-
cd example
10-
npm i
11-
npm run dev:convex -- --once
12-
```
13-
14-
Run the frontend and backend:
15-
16-
```sh
177
npm run dev
188
```
199

2010
## Testing
2111

2212
```sh
23-
rm -rf dist/ && npm run build
13+
npm run clean
14+
npm run build
2415
npm run typecheck
25-
cd example
2616
npm run lint
27-
cd ..
17+
npm run test
2818
```
2919

3020
## Deploying
3121

3222
### Building a one-off package
3323

3424
```sh
35-
rm -rf dist/ && npm run build
25+
npm run clean
26+
npm ci
3627
npm pack
3728
```
3829

3930
### Deploying a new version
4031

4132
```sh
42-
# this will change the version and commit it (if you run it in the root directory)
43-
npm version patch
44-
npm publish --dry-run
45-
# sanity check files being included
46-
npm publish
47-
git push --tags
48-
git push
33+
npm run release
4934
```
5035

51-
#### Alpha release
52-
53-
The same as above, but it requires extra flags so the release is only installed with `@alpha`:
36+
or for alpha release:
5437

5538
```sh
56-
npm version prerelease --preid alpha
57-
npm publish --tag alpha
58-
git push --tags
39+
npm run alpha
5940
```

README.md

Lines changed: 73 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -17,42 +17,44 @@ export const setDefaultValue = migrations.define({
1717
});
1818
```
1919

20-
You can then run it programmatically or from the CLI. See [below](#running-migrations-one-at-a-time).
20+
You can then run it programmatically or from the CLI. See
21+
[below](#running-migrations-one-at-a-time).
2122

2223
Migrations allow you to define functions that run on all documents in a table
2324
(or a specified subset). They run in batches asynchronously (online migration).
2425

25-
The component tracks the migrations state so it can avoid running twice,
26-
pick up where it left off (in the case of a bug or failure along the way),
27-
and expose the migration state in realtime via Convex queries.
26+
The component tracks the migrations state so it can avoid running twice, pick up
27+
where it left off (in the case of a bug or failure along the way), and expose
28+
the migration state in realtime via Convex queries.
2829

2930
See the [migration primer post](https://stack.convex.dev/intro-to-migrations)
30-
for a conceptual overview of online vs. offline migrations.
31-
If your migration is trivial and you're moving fast, also check out
31+
for a conceptual overview of online vs. offline migrations. If your migration is
32+
trivial and you're moving fast, also check out
3233
[lightweight migrations in the dashboard](https://stack.convex.dev/lightweight-zero-downtime-migrations).
3334

3435
Typical steps for doing a migration:
3536

3637
1. Modify your schema to allow old and new values. Typically this is adding a
37-
new optional field or marking a field as optional so it can be deleted.
38-
As part of this, update your code to handle both versions.
38+
new optional field or marking a field as optional so it can be deleted. As
39+
part of this, update your code to handle both versions.
3940
2. Define a migration to change the data to the new schema.
4041
3. Push the migration and schema changes.
4142
4. Run the migration(s) to completion.
42-
5. Modify your schema and code to assume the new value.
43-
Pushing this change will only succeed once all the data matches the new schema.
44-
This is the default behavior for Convex, unless you disable schema validation.
43+
5. Modify your schema and code to assume the new value. Pushing this change will
44+
only succeed once all the data matches the new schema. This is the default
45+
behavior for Convex, unless you disable schema validation.
4546

4647
See [this Stack post](https://stack.convex.dev/migrating-data-with-mutations)
4748
for walkthroughs of common use cases.
4849

4950
## Pre-requisite: Convex
5051

51-
You'll need an existing Convex project to use the component.
52-
Convex is a hosted backend platform, including a database, serverless functions,
53-
and a ton more you can learn about [here](https://docs.convex.dev/get-started).
52+
You'll need an existing Convex project to use the component. Convex is a hosted
53+
backend platform, including a database, serverless functions, and a ton more you
54+
can learn about [here](https://docs.convex.dev/get-started).
5455

55-
Run `npm create convex` or follow any of the [quickstarts](https://docs.convex.dev/home) to set one up.
56+
Run `npm create convex` or follow any of the
57+
[quickstarts](https://docs.convex.dev/home) to set one up.
5658

5759
## Installation
5860

@@ -62,12 +64,13 @@ Install the component package:
6264
npm install @convex-dev/migrations
6365
```
6466

65-
Create a `convex.config.ts` file in your app's `convex/` folder and install the component by calling `use`:
67+
Create a `convex.config.ts` file in your app's `convex/` folder and install the
68+
component by calling `use`:
6669

6770
```ts
6871
// convex/convex.config.ts
6972
import { defineApp } from "convex/server";
70-
import migrations from "@convex-dev/migrations/convex.config";
73+
import migrations from "@convex-dev/migrations/convex.config.js";
7174

7275
const app = defineApp();
7376
app.use(migrations);
@@ -77,11 +80,11 @@ export default app;
7780

7881
## Initialization
7982

80-
Examples below are assuming the code is in `convex/migrations.ts`.
81-
This is not a requirement.
82-
If you want to use a different file, make sure to change the examples below from
83-
`internal.migrations.*` to your new file name, like `internal.myFolder.myMigrationsFile.*`
84-
or CLI arguments like `migrations:*` to `myFolder/myMigrationsFile:*`.
83+
Examples below are assuming the code is in `convex/migrations.ts`. This is not a
84+
requirement. If you want to use a different file, make sure to change the
85+
examples below from `internal.migrations.*` to your new file name, like
86+
`internal.myFolder.myMigrationsFile.*` or CLI arguments like `migrations:*` to
87+
`myFolder/myMigrationsFile:*`.
8588

8689
```ts
8790
import { Migrations } from "@convex-dev/migrations";
@@ -92,10 +95,12 @@ export const migrations = new Migrations<DataModel>(components.migrations);
9295
export const run = migrations.runner();
9396
```
9497

95-
The type parameter `DataModel` is optional. It provides type safety for migration definitions.
96-
As always, database operations in migrations will abide by your schema definition at runtime.
97-
**Note**: if you use [custom functions](https://stack.convex.dev/custom-functions)
98-
to override `internalMutation`, see [below](#override-the-internalmutation-to-apply-custom-db-behavior).
98+
The type parameter `DataModel` is optional. It provides type safety for
99+
migration definitions. As always, database operations in migrations will abide
100+
by your schema definition at runtime. **Note**: if you use
101+
[custom functions](https://stack.convex.dev/custom-functions) to override
102+
`internalMutation`, see
103+
[below](#override-the-internalmutation-to-apply-custom-db-behavior).
99104

100105
## Define migrations
101106

@@ -116,8 +121,8 @@ export const setDefaultValue = migrations.define({
116121

117122
### Shorthand syntax
118123

119-
Since the most common migration involves patching each document,
120-
if you return an object, it will be applied as a patch automatically.
124+
Since the most common migration involves patching each document, if you return
125+
an object, it will be applied as a patch automatically.
121126

122127
```ts
123128
export const clearField = migrations.define({
@@ -162,20 +167,22 @@ To run it from the CLI:
162167
npx convex run convex/migrations.ts:runIt # or shorthand: migrations:runIt
163168
```
164169

165-
**Note**: pass the `--prod` argument to run this and below commands in production
170+
**Note**: pass the `--prod` argument to run this and below commands in
171+
production
166172

167173
Running it from the dashboard:
168174

169175
![Dashboard screenshot](./dashboard_screenshot.png)
170176

171-
You can also expose a general-purpose function to run your migrations.
172-
For example, in `convex/migrations.ts` add:
177+
You can also expose a general-purpose function to run your migrations. For
178+
example, in `convex/migrations.ts` add:
173179

174180
```ts
175181
export const run = migrations.runner();
176182
```
177183

178-
Then run it with the [function name](https://docs.convex.dev/functions/query-functions#query-names):
184+
Then run it with the
185+
[function name](https://docs.convex.dev/functions/query-functions#query-names):
179186

180187
```sh
181188
npx convex run migrations:run '{fn: "migrations:setDefaultValue"}'
@@ -198,10 +205,10 @@ await migrations.runOne(ctx, internal.example.setDefaultValue);
198205
unless you manually specify `cursor`.
199206
- If you provide an explicit `cursor` (`null` means to start at the beginning),
200207
it will start from there.
201-
- If you pass `true` for `dryRun` then it will run one batch and then throw,
202-
so no changes are committed, and you can see what it would have done.
203-
See [below](#test-a-migration-with-dryrun)
204-
This is good for validating it does what you expect.
208+
- If you pass `true` for `dryRun` then it will run one batch and then throw, so
209+
no changes are committed, and you can see what it would have done. See
210+
[below](#test-a-migration-with-dryrun) This is good for validating it does
211+
what you expect.
205212

206213
## Running migrations serially
207214

@@ -228,8 +235,8 @@ Then just run:
228235
npx convex run migrations:runAll # migrations:runAll is equivalent to convex/migrations.ts:runAll on the CLI
229236
```
230237

231-
With the `runner` functions, you can pass a "next" argument to run
232-
a series of migrations after the first:
238+
With the `runner` functions, you can pass a "next" argument to run a series of
239+
migrations after the first:
233240

234241
```sh
235242
npx convex run migrations:runIt '{next:["migrations:clearField"]}'
@@ -252,24 +259,23 @@ await migrations.runSerially(ctx, [
252259
- If a migration is already in progress when attempted, it will no-op.
253260
- If a migration had already completed, it will skip it.
254261
- If a migration had partial progress, it will resume from where it left off.
255-
- If a migration fails or is canceled, it will not continue on,
256-
in case you had some dependencies between the migrations.
257-
Call the series again to retry.
262+
- If a migration fails or is canceled, it will not continue on, in case you had
263+
some dependencies between the migrations. Call the series again to retry.
258264

259265
Note: if you start multiple serial migrations, the behavior is:
260266

261267
- If they don't overlap on functions, they will happily run in parallel.
262-
- If they have a function in common and one completes before the other
263-
attempts it, the second will just skip it.
268+
- If they have a function in common and one completes before the other attempts
269+
it, the second will just skip it.
264270
- If they have a function in common and one is in progress, the second will
265271
no-op and not run any further migrations in its series.
266272

267273
## Operations
268274

269275
### Test a migration with dryRun
270276

271-
Before running a migration that may irreversibly change data, you can validate
272-
a batch by passing `dryRun` to any `runner` or `runOne` command:
277+
Before running a migration that may irreversibly change data, you can validate a
278+
batch by passing `dryRun` to any `runner` or `runOne` command:
273279

274280
```sh
275281
npx convex run migrations:runIt '{dryRun: true}'
@@ -289,7 +295,8 @@ from a known good point as you iterate on the code.
289295

290296
### Stop a migration
291297

292-
You can stop a migration from the CLI or dashboard, calling the component API directly:
298+
You can stop a migration from the CLI or dashboard, calling the component API
299+
directly:
293300

294301
```sh
295302
npx convex run --component migrations lib:cancel '{name: "migrations:myMigration"}'
@@ -303,14 +310,14 @@ await migrations.cancel(ctx, internal.migrations.myMigration);
303310

304311
### Get the status of migrations
305312

306-
To see the live status of migrations as they progress, you can query it via the CLI:
313+
To see the live status of migrations as they progress, you can query it via the
314+
CLI:
307315

308316
```sh
309317
npx convex run --component migrations lib:getStatus --watch
310318
```
311319

312-
The `--watch` will live-update the status as it changes.
313-
Or programmatically:
320+
The `--watch` will live-update the status as it changes. Or programmatically:
314321

315322
```ts
316323
const status: MigrationStatus[] = await migrations.getStatus(ctx, {
@@ -343,10 +350,12 @@ npx convex deploy --cmd 'npm run build' && npx convex run convex/migrations.ts:r
343350

344351
### Override the internalMutation to apply custom DB behavior
345352

346-
You can customize which `internalMutation` implementation the underly migration should use.
353+
You can customize which `internalMutation` implementation the underly migration
354+
should use.
347355

348-
This might be important if you use [custom functions](https://stack.convex.dev/custom-functions)
349-
to intercept database writes to apply validation or
356+
This might be important if you use
357+
[custom functions](https://stack.convex.dev/custom-functions) to intercept
358+
database writes to apply validation or
350359
[trigger operations on changes](https://stack.convex.dev/triggers).
351360

352361
Assuming you define your own `internalMutation` in `convex/functions.ts`:
@@ -361,15 +370,14 @@ export const migrations = new Migrations(components.migrations, {
361370
});
362371
```
363372

364-
See [this article](https://stack.convex.dev/migrating-data-with-mutations)
365-
for more information on usage and advanced patterns.
373+
See [this article](https://stack.convex.dev/migrating-data-with-mutations) for
374+
more information on usage and advanced patterns.
366375

367376
### Custom batch size
368377

369378
The component will fetch your data in batches of 100, and call your function on
370-
each document in a batch.
371-
If you want to change the batch size, you can specify it.
372-
This can be useful if your documents are large, to avoid running over the
379+
each document in a batch. If you want to change the batch size, you can specify
380+
it. This can be useful if your documents are large, to avoid running over the
373381
[transaction limit](https://docs.convex.dev/production/state/limits#transactions),
374382
or if your documents are updating frequently and you are seeing OCC conflicts
375383
while migrating.
@@ -393,12 +401,11 @@ await migrations.runOne(ctx, internal.migrations.clearField, {
393401
### Parallelizing batches
394402

395403
Each batch is processed serially, but within a batch you can have each
396-
`migrateOne` call run in parallel if you pass `parallelize: true`.
397-
If you do so, ensure your callback doesn't assume that each call is isolated.
398-
For instance, if each call reads then updates the same counter, then multiple
399-
functions in the same batch could read the same counter value, and get off by
400-
one.
401-
As a result, migrations are run serially by default.
404+
`migrateOne` call run in parallel if you pass `parallelize: true`. If you do so,
405+
ensure your callback doesn't assume that each call is isolated. For instance, if
406+
each call reads then updates the same counter, then multiple functions in the
407+
same batch could read the same counter value, and get off by one. As a result,
408+
migrations are run serially by default.
402409

403410
```ts
404411
export const clearField = migrations.define({
@@ -411,8 +418,9 @@ export const clearField = migrations.define({
411418
### Shorthand running syntax:
412419

413420
For those that don't want to type out `migrations:myNewMigration` every time
414-
they run a migration from the CLI or dashboard, especially if you define your migrations
415-
elsewhere like `ops/db/migrations:myNewMigration`, you can configure a prefix:
421+
they run a migration from the CLI or dashboard, especially if you define your
422+
migrations elsewhere like `ops/db/migrations:myNewMigration`, you can configure
423+
a prefix:
416424

417425
```ts
418426
export const migrations = new Migrations(components.migrations, {

0 commit comments

Comments
 (0)