@samebase/alchemy-convex 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +23 -13
- package/lib/index.js.map +1 -1
- package/package.json +3 -3
- package/src/State.ts +34 -29
- package/src/store/convex/_generated/api.d.ts +4 -0
- package/src/store/convex/auth.config.ts +14 -0
- package/src/store/convex/reader.ts +131 -0
- package/src/store/convex/runRecord.ts +41 -0
- package/src/store/convex/schema.ts +3 -1
- package/src/store/convex/state.ts +47 -21
- package/src/store/convex/version.ts +6 -4
- package/src/store/package.json +1 -1
package/README.md
CHANGED
|
@@ -135,11 +135,20 @@ is set must be the slug of that team, checked against its projects, and a token
|
|
|
135
135
|
fails the run. The Convex CLI login needs the slug or the id. The first run of a team creates
|
|
136
136
|
the project `alchemy-state` and pushes the store functions to its
|
|
137
137
|
production deployment with the Convex CLI of the app; a later version of this package pushes a
|
|
138
|
-
newer store when it finds an older one
|
|
138
|
+
newer store when it finds an older one. A store that is newer than the package fails the run with
|
|
139
|
+
both versions, so the repositories of a team upgrade the package together. Each run makes a
|
|
139
140
|
deploy key of that deployment that can only run the store's internal functions, and deletes it at
|
|
140
141
|
the end. Rows are in the tables `resources` and `outputs` in the dashboard, under the stack name.
|
|
141
142
|
The store has no lock: run one deploy of a stage at a time, such as with a CI concurrency group.
|
|
142
|
-
The
|
|
143
|
+
The store and its readers (Samebase) are released and upgraded together.
|
|
144
|
+
|
|
145
|
+
Store version 3 supports native subscriptions. A trusted server checks repository access, then
|
|
146
|
+
calls internal `reader:authorize({ repository, subject })` with a deployment credential. It gives
|
|
147
|
+
the returned token to a separate `ConvexClient` connected to the state deployment. The client
|
|
148
|
+
subscribes to `reader:repository({})`; the verified token selects the repository. The token has a
|
|
149
|
+
five-minute lifetime and permits redacted reads only. The server checks access again on renewal.
|
|
150
|
+
The store uses its own native signing key and JWKS, so no extra signing secret is required.
|
|
151
|
+
See [the reader contract](docs/design/convex-state.md#repository-subscriptions-090).
|
|
143
152
|
|
|
144
153
|
### What the output records about a run
|
|
145
154
|
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/Credentials.ts","../src/ManagementApi.ts","../src/Providers.ts","../src/Push.ts","../src/Deployment.ts","../src/Project.ts","../src/RunRecord.ts","../src/State.ts"],"mappings":";;;;;;;;;;;;;;UA6BiB;;WAEN,aAAa,SAAS;;WAEtB;;UAGM;;WAEN,aAAa,OAAO,OAAO;;WAE3B,gBAAgB,OAAO;;WAEvB,WAAW,OAAO,OAAO,SAAS;;;qBAGhC,oBAAoB;;qBAKpB;;qBAGA;;;;qBAOA,yBAAyB;;;;;;;;;qBAiCzB,kBAAiB,MAAM,MAAM;;qBA0B7B,aAAc;WAChB,cAAc,SAAS;WACvB,YAAY,SAAS;MAC5B,MAAM,MAAM;;;KC3GJ,mBAAmB,kBAAkB;KACrC,mBAAmB,kBAAkB;;UAGhC,YAAY;WAClB,OAAO;WACP;WACA,UAAU;;;;;;;;;;;;;qBAQR,uBAAuB;UAuBnB;;WAEN,UAAU,GACjB,mBACA,MAAM,QAAQ,qBAAqB,QAAQ,YAAY,QACpD,OAAO,OAAO,GAAG;;WAEb,cACP,mBACA,MAAM,QAAQ,qBAAqB,QAAQ,0BACxC,OAAO,aAAa;;WAEhB,oBAAoB,GAC3B,mBACA,6BACA,WAAW,SAAS,kBACpB,MAAM,QAAQ,qBAAqB,QAAQ,YAAY,QACpD,OAAO,OAAO,GAAG;;;;;;;;WAQb,gBACP,sCACG,OAAO,eAAe;;;;;;;;WAQlB,oBAAoB,mBAAmB,OAAO;;;;;WAK9C,YAAY,OAAO,SAAS,qBAAqB;;;qBAM/C,sBAAsB;;;;qBC1FtB,kBAAkB;;;;;;qBAOlB,YAAa,cAAa,MAAM,MAAM,iBAA2B,MAAA,MAAA,8CAAA,mCAAA,oDAAA;;;;KC+BlE,oBAAoB,SAAS;;;;;;KAO7B;;WAIG;;;;;;;;WAQA;;;;;;;WAOA;;;;;;qBAkCF,0BAA0B;MAIxB;;;;;;;qBAMF,0BAA0B;MAOxB;;;;;;;;;qBAMF,uBAAuB;MAMrB;;;;;;;qBAQF,2BAA2B;MAIzB;;;;;;;qBAMF,oCAAoC;MAIlC;;;;;;qBAMF,kCAAkC;MAIhC;;;qBAuCF,oBACX;EACG;EAAa;;;;UC5HR;;WAEC;aAAoB;;;;;;;;WAOpB;;;;;;WAMA,SAAS;;WAET,MAAM,SAAS,eAAe;;KAG7B,mBACP;;WAEU;MAEV;;WAEU;;;;;WAKA;;;UAIL;WACC;WACA,MAAM;;WAEN;;WAEA;;WAEA;;WAEA;;WAEA;;UAGM,6BAA6B;;WAEnC;;WAEA;;YAGC,aAAa,8BAEvB,iBACA,6BAEA;;KAQU,kBAAkB,+BAA8B,KACxD,UAAU,kBACR,WAAW;;;;;qBAWJ,wBAAwB;MAGtB;;;;;;;;;;;;qBAeF,cAAU,YACV,OAAS,oBAAe,OAAA,OAAA,mBAAA;;;;;;EAYvB,MAAA,YAAM;IAAc;IAAgB;QAAgB,OAAA,OAAA;;;;;;;;;;qBAMrD,iCAAiC;MAU/B;;;;;;qBAMF,qCAAqC;MAInC;;;;;;;;;qBAMF,4BAA4B;MAS1B;;;;;KC7MH,mBAAmB;KAEnB;;WAGG;;WAEA;;WAEA,mBAAmB;;WAEnB;;;WAIA;;WAEA;;UAGE;WACN;WACA;WACA;WACA;WACA;WACA;;YAGC,UAAU,2BAA2B,cAAc,0BAA0B;qBAC5E,2BAAO,cAAA;;;;;;;qBAGP,0BAA0B;MAIxB;;;;;;;;;;;;qBASF,gCAAgC;MAS9B;;;;;;;;qBAOF,yBAAyB;MAKvB;;;;;;qBAMF,+BAA+B;MAI7B;;;;;;;qBAMF,wBAAwB;MAItB;;;;;qBC5GF;;UAMI;WACN;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;WACA;;WAEA;;;;;qBAGE,uBAAuB;MAGrB;;;UAME;WACN;WACA,KAAK,SAAS;;;;;;;;qBAuIZ,YAAa,OAAO,mBAAiB,OAAO,OAAO,WAAW;;;;;;;qBAgB9D,gBAAiB,iBAAiB,QAAQ;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/Credentials.ts","../src/ManagementApi.ts","../src/Providers.ts","../src/Push.ts","../src/Deployment.ts","../src/Project.ts","../src/RunRecord.ts","../src/State.ts"],"mappings":";;;;;;;;;;;;;;UA6BiB;;WAEN,aAAa,SAAS;;WAEtB;;UAGM;;WAEN,aAAa,OAAO,OAAO;;WAE3B,gBAAgB,OAAO;;WAEvB,WAAW,OAAO,OAAO,SAAS;;;qBAGhC,oBAAoB;;qBAKpB;;qBAGA;;;;qBAOA,yBAAyB;;;;;;;;;qBAiCzB,kBAAiB,MAAM,MAAM;;qBA0B7B,aAAc;WAChB,cAAc,SAAS;WACvB,YAAY,SAAS;MAC5B,MAAM,MAAM;;;KC3GJ,mBAAmB,kBAAkB;KACrC,mBAAmB,kBAAkB;;UAGhC,YAAY;WAClB,OAAO;WACP;WACA,UAAU;;;;;;;;;;;;;qBAQR,uBAAuB;UAuBnB;;WAEN,UAAU,GACjB,mBACA,MAAM,QAAQ,qBAAqB,QAAQ,YAAY,QACpD,OAAO,OAAO,GAAG;;WAEb,cACP,mBACA,MAAM,QAAQ,qBAAqB,QAAQ,0BACxC,OAAO,aAAa;;WAEhB,oBAAoB,GAC3B,mBACA,6BACA,WAAW,SAAS,kBACpB,MAAM,QAAQ,qBAAqB,QAAQ,YAAY,QACpD,OAAO,OAAO,GAAG;;;;;;;;WAQb,gBACP,sCACG,OAAO,eAAe;;;;;;;;WAQlB,oBAAoB,mBAAmB,OAAO;;;;;WAK9C,YAAY,OAAO,SAAS,qBAAqB;;;qBAM/C,sBAAsB;;;;qBC1FtB,kBAAkB;;;;;;qBAOlB,YAAa,cAAa,MAAM,MAAM,iBAA2B,MAAA,MAAA,8CAAA,mCAAA,oDAAA;;;;KC+BlE,oBAAoB,SAAS;;;;;;KAO7B;;WAIG;;;;;;;;WAQA;;;;;;;WAOA;;;;;;qBAkCF,0BAA0B;MAIxB;;;;;;;qBAMF,0BAA0B;MAOxB;;;;;;;;;qBAMF,uBAAuB;MAMrB;;;;;;;qBAQF,2BAA2B;MAIzB;;;;;;;qBAMF,oCAAoC;MAIlC;;;;;;qBAMF,kCAAkC;MAIhC;;;qBAuCF,oBACX;EACG;EAAa;;;;UC5HR;;WAEC;aAAoB;;;;;;;;WAOpB;;;;;;WAMA,SAAS;;WAET,MAAM,SAAS,eAAe;;KAG7B,mBACP;;WAEU;MAEV;;WAEU;;;;;WAKA;;;UAIL;WACC;WACA,MAAM;;WAEN;;WAEA;;WAEA;;WAEA;;WAEA;;UAGM,6BAA6B;;WAEnC;;WAEA;;YAGC,aAAa,8BAEvB,iBACA,6BAEA;;KAQU,kBAAkB,+BAA8B,KACxD,UAAU,kBACR,WAAW;;;;;qBAWJ,wBAAwB;MAGtB;;;;;;;;;;;;qBAeF,cAAU,YACV,OAAS,oBAAe,OAAA,OAAA,mBAAA;;;;;;EAYvB,MAAA,YAAM;IAAc;IAAgB;QAAgB,OAAA,OAAA;;;;;;;;;;qBAMrD,iCAAiC;MAU/B;;;;;;qBAMF,qCAAqC;MAInC;;;;;;;;;qBAMF,4BAA4B;MAS1B;;;;;KC7MH,mBAAmB;KAEnB;;WAGG;;WAEA;;WAEA,mBAAmB;;WAEnB;;;WAIA;;WAEA;;UAGE;WACN;WACA;WACA;WACA;WACA;WACA;;YAGC,UAAU,2BAA2B,cAAc,0BAA0B;qBAC5E,2BAAO,cAAA;;;;;;;qBAGP,0BAA0B;MAIxB;;;;;;;;;;;;qBASF,gCAAgC;MAS9B;;;;;;;;qBAOF,yBAAyB;MAKvB;;;;;;qBAMF,+BAA+B;MAI7B;;;;;;;qBAMF,wBAAwB;MAItB;;;;;qBC5GF;;UAMI;WACN;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;WACA;;WAEA;;;;;qBAGE,uBAAuB;MAGrB;;;UAME;WACN;WACA,KAAK,SAAS;;;;;;;;qBAuIZ,YAAa,OAAO,mBAAiB,OAAO,OAAO,WAAW;;;;;;;qBAgB9D,gBAAiB,iBAAiB,QAAQ;;;;qBCzH1C;;;;;;;;;qBA+WA,QACX;WAAoB;MACnB,MAAM,MAAM,cAAc,oBAAoB"}
|
package/lib/index.js
CHANGED
|
@@ -1555,8 +1555,18 @@ const makeFunctionApi = (url, key) => ({ call: (path, args) => post(`${url}/api/
|
|
|
1555
1555
|
/** The value of a reply, or the Convex message, which names the function and the cause, such as a missing key action. */
|
|
1556
1556
|
const valueOf = (reply) => reply.status === "success" ? Effect.succeed(reply.value) : Effect.fail(failure(reply.errorMessage.trim()));
|
|
1557
1557
|
/** The functions of the store with Alchemy's encoding: the JSON text of encodeState. */
|
|
1558
|
-
const remoteOf = (api) => {
|
|
1558
|
+
const remoteOf = (api, record) => {
|
|
1559
1559
|
const run = (name, args) => api.call(`state:${name}`, args).pipe(Effect.flatMap(valueOf));
|
|
1560
|
+
const write = (name, args) => Effect.gen(function* () {
|
|
1561
|
+
const currentRun = record === void 0 ? void 0 : {
|
|
1562
|
+
...record,
|
|
1563
|
+
recordedAt: new Date(yield* Clock.currentTimeMillis).toISOString()
|
|
1564
|
+
};
|
|
1565
|
+
return yield* run(name, {
|
|
1566
|
+
...args,
|
|
1567
|
+
run: currentRun
|
|
1568
|
+
});
|
|
1569
|
+
});
|
|
1560
1570
|
const strings = (name, args) => run(name, args).pipe(Effect.flatMap(decode(Schema.Array(Schema.String), name)));
|
|
1561
1571
|
const optional = (name, args) => run(name, args).pipe(Effect.flatMap(decode(Schema.NullOr(Schema.String), name)));
|
|
1562
1572
|
const encode = (value) => JSON.stringify(encodeState(value));
|
|
@@ -1580,13 +1590,13 @@ const remoteOf = (api) => {
|
|
|
1580
1590
|
stack: r.stack,
|
|
1581
1591
|
stage: r.stage
|
|
1582
1592
|
}).pipe(Effect.map((text) => text === null ? void 0 : JSON.parse(text, reviveState))),
|
|
1583
|
-
set: (r) =>
|
|
1593
|
+
set: (r) => write("set", {
|
|
1584
1594
|
stack: r.stack,
|
|
1585
1595
|
stage: r.stage,
|
|
1586
1596
|
fqn: r.fqn,
|
|
1587
1597
|
value: encode(r.value)
|
|
1588
1598
|
}),
|
|
1589
|
-
delete: (r) =>
|
|
1599
|
+
delete: (r) => write("remove", {
|
|
1590
1600
|
stack: r.stack,
|
|
1591
1601
|
stage: r.stage,
|
|
1592
1602
|
fqn: r.fqn
|
|
@@ -1595,7 +1605,7 @@ const remoteOf = (api) => {
|
|
|
1595
1605
|
stack: r.stack,
|
|
1596
1606
|
stage: r.stage
|
|
1597
1607
|
}),
|
|
1598
|
-
setOutput: (r) =>
|
|
1608
|
+
setOutput: (r) => write("setOutput", {
|
|
1599
1609
|
stack: r.stack,
|
|
1600
1610
|
stage: r.stage,
|
|
1601
1611
|
value: encode(r.value)
|
|
@@ -1618,7 +1628,7 @@ const storeDirectory = () => join(dirname(fileURLToPath(import.meta.url)), "..",
|
|
|
1618
1628
|
*/
|
|
1619
1629
|
const pushStore = (options, deployment) => Effect.gen(function* () {
|
|
1620
1630
|
const cli = yield* installedCli(join(options.store, ".."));
|
|
1621
|
-
yield* Effect.logInfo(`Convex state: pushing the store version
|
|
1631
|
+
yield* Effect.logInfo(`Convex state: pushing the store version 3 to ${deployment.name}`);
|
|
1622
1632
|
yield* withPushKey(options.api, deployment.name, PUSH_KEY_ACTIONS, (key) => push(options.spawner, key, {
|
|
1623
1633
|
deployment: deployment.name,
|
|
1624
1634
|
url: deployment.deploymentUrl,
|
|
@@ -1681,17 +1691,17 @@ const makeConvexState = (options) => Effect.gen(function* () {
|
|
|
1681
1691
|
current = next;
|
|
1682
1692
|
return next.call(path, args);
|
|
1683
1693
|
})))) };
|
|
1684
|
-
|
|
1685
|
-
if (version === void 0 || version <
|
|
1694
|
+
let version = yield* storeVersion(functions);
|
|
1695
|
+
if (version === void 0 || version < 3) {
|
|
1686
1696
|
if (version === void 0 && deployment.lastDeployTime) return yield* failure(`project ${STORE_PROJECT_NAME} (${project.id}) of team ${team} has code that is not the state store, and Convex.state does not push over it. Rename that project in the Convex dashboard.`);
|
|
1687
|
-
|
|
1688
|
-
if (
|
|
1697
|
+
version = yield* storeVersion(functions);
|
|
1698
|
+
if (version === void 0 || version < 3) {
|
|
1689
1699
|
yield* pushStore(options, deployment);
|
|
1690
|
-
|
|
1691
|
-
if (pushed === void 0 || pushed < 2) return yield* failure(`${deployment.name} answers store version ${pushed ?? "none"} after the push of version 2.`);
|
|
1700
|
+
version = yield* storeVersion(functions);
|
|
1692
1701
|
}
|
|
1693
|
-
}
|
|
1694
|
-
|
|
1702
|
+
}
|
|
1703
|
+
if (version !== 3) return yield* failure(`${deployment.name} answers store version ${version ?? "none"}, and this package needs store version 3.`);
|
|
1704
|
+
const remote = remoteOf(functions, options.run);
|
|
1695
1705
|
/** The stack's output plus the record, when the run has one and the output has a place for it. */
|
|
1696
1706
|
const documentOf = (request) => Effect.gen(function* () {
|
|
1697
1707
|
const { run } = options;
|