@samebase/alchemy-convex 0.5.0 → 0.6.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.
@@ -8,7 +8,7 @@
8
8
  * @module
9
9
  */
10
10
 
11
- import type {
11
+ import {
12
12
  ActionBuilder,
13
13
  HttpActionBuilder,
14
14
  MutationBuilder,
@@ -19,15 +19,6 @@ import type {
19
19
  GenericDatabaseReader,
20
20
  GenericDatabaseWriter,
21
21
  } from "convex/server";
22
- import {
23
- actionGeneric,
24
- httpActionGeneric,
25
- queryGeneric,
26
- mutationGeneric,
27
- internalActionGeneric,
28
- internalMutationGeneric,
29
- internalQueryGeneric,
30
- } from "convex/server";
31
22
  import type { DataModel } from "./dataModel.js";
32
23
 
33
24
  /**
@@ -49,7 +40,7 @@ type Env = {
49
40
  * @param func - The query function. It receives a {@link QueryCtx} as its first argument.
50
41
  * @returns The wrapped query. Include this as an `export` to name it and make it accessible.
51
42
  */
52
- export const query: QueryBuilder<DataModel, "public"> = queryGeneric;
43
+ export declare const query: QueryBuilder<DataModel, "public">;
53
44
 
54
45
  /**
55
46
  * Define a query that is only accessible from other Convex functions (but not from the client).
@@ -59,8 +50,7 @@ export const query: QueryBuilder<DataModel, "public"> = queryGeneric;
59
50
  * @param func - The query function. It receives a {@link QueryCtx} as its first argument.
60
51
  * @returns The wrapped query. Include this as an `export` to name it and make it accessible.
61
52
  */
62
- export const internalQuery: QueryBuilder<DataModel, "internal"> =
63
- internalQueryGeneric;
53
+ export declare const internalQuery: QueryBuilder<DataModel, "internal">;
64
54
 
65
55
  /**
66
56
  * Define a mutation in this Convex app's public API.
@@ -70,7 +60,7 @@ export const internalQuery: QueryBuilder<DataModel, "internal"> =
70
60
  * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
71
61
  * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
72
62
  */
73
- export const mutation: MutationBuilder<DataModel, "public"> = mutationGeneric;
63
+ export declare const mutation: MutationBuilder<DataModel, "public">;
74
64
 
75
65
  /**
76
66
  * Define a mutation that is only accessible from other Convex functions (but not from the client).
@@ -80,8 +70,7 @@ export const mutation: MutationBuilder<DataModel, "public"> = mutationGeneric;
80
70
  * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
81
71
  * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
82
72
  */
83
- export const internalMutation: MutationBuilder<DataModel, "internal"> =
84
- internalMutationGeneric;
73
+ export declare const internalMutation: MutationBuilder<DataModel, "internal">;
85
74
 
86
75
  /**
87
76
  * Define an action in this Convex app's public API.
@@ -94,7 +83,7 @@ export const internalMutation: MutationBuilder<DataModel, "internal"> =
94
83
  * @param func - The action. It receives an {@link ActionCtx} as its first argument.
95
84
  * @returns The wrapped action. Include this as an `export` to name it and make it accessible.
96
85
  */
97
- export const action: ActionBuilder<DataModel, "public"> = actionGeneric;
86
+ export declare const action: ActionBuilder<DataModel, "public">;
98
87
 
99
88
  /**
100
89
  * Define an action that is only accessible from other Convex functions (but not from the client).
@@ -102,8 +91,7 @@ export const action: ActionBuilder<DataModel, "public"> = actionGeneric;
102
91
  * @param func - The function. It receives an {@link ActionCtx} as its first argument.
103
92
  * @returns The wrapped function. Include this as an `export` to name it and make it accessible.
104
93
  */
105
- export const internalAction: ActionBuilder<DataModel, "internal"> =
106
- internalActionGeneric;
94
+ export declare const internalAction: ActionBuilder<DataModel, "internal">;
107
95
 
108
96
  /**
109
97
  * Define an HTTP action.
@@ -116,9 +104,15 @@ export const internalAction: ActionBuilder<DataModel, "internal"> =
116
104
  * and a Fetch API `Request` object as its second.
117
105
  * @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up.
118
106
  */
119
- export const httpAction: HttpActionBuilder = httpActionGeneric;
120
- export const env: Env = (globalThis as unknown as { process: { env: Env } })
121
- .process.env;
107
+ export declare const httpAction: HttpActionBuilder;
108
+
109
+ /**
110
+ * Typesafe environment variables.
111
+ *
112
+ * This includes platform-provided env vars and any variables declared in
113
+ * `convex.config.ts`.
114
+ */
115
+ export declare const env: Env;
122
116
 
123
117
  /**
124
118
  * A set of services for use within Convex query functions.
@@ -126,7 +120,8 @@ export const env: Env = (globalThis as unknown as { process: { env: Env } })
126
120
  * The query context is passed as the first argument to any Convex query
127
121
  * function run on the server.
128
122
  *
129
- * If you're using code generation, use the `QueryCtx` type in `convex/_generated/server.d.ts` instead.
123
+ * This differs from the {@link MutationCtx} because all of the services are
124
+ * read-only.
130
125
  */
131
126
  export type QueryCtx = GenericQueryCtx<DataModel>;
132
127
 
@@ -135,8 +130,6 @@ export type QueryCtx = GenericQueryCtx<DataModel>;
135
130
  *
136
131
  * The mutation context is passed as the first argument to any Convex mutation
137
132
  * function run on the server.
138
- *
139
- * If you're using code generation, use the `MutationCtx` type in `convex/_generated/server.d.ts` instead.
140
133
  */
141
134
  export type MutationCtx = GenericMutationCtx<DataModel>;
142
135
 
@@ -0,0 +1,101 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * Generated utilities for implementing server-side Convex query and mutation functions.
4
+ *
5
+ * THIS CODE IS AUTOMATICALLY GENERATED.
6
+ *
7
+ * To regenerate, run `npx convex dev`.
8
+ * @module
9
+ */
10
+
11
+ import {
12
+ actionGeneric,
13
+ httpActionGeneric,
14
+ queryGeneric,
15
+ mutationGeneric,
16
+ internalActionGeneric,
17
+ internalMutationGeneric,
18
+ internalQueryGeneric,
19
+ } from "convex/server";
20
+
21
+ /**
22
+ * Define a query in this Convex app's public API.
23
+ *
24
+ * This function will be allowed to read your Convex database and will be accessible from the client.
25
+ *
26
+ * @param func - The query function. It receives a {@link QueryCtx} as its first argument.
27
+ * @returns The wrapped query. Include this as an `export` to name it and make it accessible.
28
+ */
29
+ export const query = queryGeneric;
30
+
31
+ /**
32
+ * Define a query that is only accessible from other Convex functions (but not from the client).
33
+ *
34
+ * This function will be allowed to read from your Convex database. It will not be accessible from the client.
35
+ *
36
+ * @param func - The query function. It receives a {@link QueryCtx} as its first argument.
37
+ * @returns The wrapped query. Include this as an `export` to name it and make it accessible.
38
+ */
39
+ export const internalQuery = internalQueryGeneric;
40
+
41
+ /**
42
+ * Define a mutation in this Convex app's public API.
43
+ *
44
+ * This function will be allowed to modify your Convex database and will be accessible from the client.
45
+ *
46
+ * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
47
+ * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
48
+ */
49
+ export const mutation = mutationGeneric;
50
+
51
+ /**
52
+ * Define a mutation that is only accessible from other Convex functions (but not from the client).
53
+ *
54
+ * This function will be allowed to modify your Convex database. It will not be accessible from the client.
55
+ *
56
+ * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
57
+ * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
58
+ */
59
+ export const internalMutation = internalMutationGeneric;
60
+
61
+ /**
62
+ * Define an action in this Convex app's public API.
63
+ *
64
+ * An action is a function which can execute any JavaScript code, including non-deterministic
65
+ * code and code with side-effects, like calling third-party services.
66
+ * They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive.
67
+ * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.
68
+ *
69
+ * @param func - The action. It receives an {@link ActionCtx} as its first argument.
70
+ * @returns The wrapped action. Include this as an `export` to name it and make it accessible.
71
+ */
72
+ export const action = actionGeneric;
73
+
74
+ /**
75
+ * Define an action that is only accessible from other Convex functions (but not from the client).
76
+ *
77
+ * @param func - The function. It receives an {@link ActionCtx} as its first argument.
78
+ * @returns The wrapped function. Include this as an `export` to name it and make it accessible.
79
+ */
80
+ export const internalAction = internalActionGeneric;
81
+
82
+ /**
83
+ * Define an HTTP action.
84
+ *
85
+ * The wrapped function will be used to respond to HTTP requests received
86
+ * by a Convex deployment if the requests matches the path and method where
87
+ * this action is routed. Be sure to route your httpAction in `convex/http.js`.
88
+ *
89
+ * @param func - The function. It receives an {@link ActionCtx} as its first argument
90
+ * and a Fetch API `Request` object as its second.
91
+ * @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up.
92
+ */
93
+ export const httpAction = httpActionGeneric;
94
+
95
+ /**
96
+ * Typesafe environment variables.
97
+ *
98
+ * This includes platform-provided env vars and any variables declared in
99
+ * `convex.config.ts`.
100
+ */
101
+ export const env = process.env;
@@ -1,13 +1,25 @@
1
- // The state functions. A component function is not part of the public API of
2
- // the app: only POST /api/function with a deploy key reaches it, and that key
3
- // needs `deployment:data:view` for a query and `deployment:data:write` for a
4
- // mutation (measured).
1
+ // The state functions of the alchemy-state project: one project for each
2
+ // Convex team, pushed by Convex.state() from this directory. Every function
3
+ // is internal: a public function of a root app answers anyone who knows the
4
+ // deployment URL, with no key (measured). An internal function answers only
5
+ // POST /api/function with a deploy key of the production deployment, the
6
+ // call that `convex run` makes.
5
7
  //
6
8
  // A stage holds one row for each resource of its stack, so the reads of one
7
- // stage collect all rows.
9
+ // stage collect all rows. The function names are a wire contract: Samebase
10
+ // reads `stacks` and `getOutput` by name, and an older client calls an older
11
+ // set of names. Add functions; never rename or remove one.
8
12
  import { v } from "convex/values";
9
13
  import type { QueryCtx } from "./_generated/server.js";
10
- import { mutation, query } from "./_generated/server.js";
14
+ import { internalMutation, internalQuery } from "./_generated/server.js";
15
+ import { STORE_VERSION } from "./version.ts";
16
+
17
+ /** The wire version of this store, compared with the client's STORE_VERSION. */
18
+ export const version = internalQuery({
19
+ args: {},
20
+ returns: v.number(),
21
+ handler: async () => STORE_VERSION,
22
+ });
11
23
 
12
24
  const stage = { stack: v.string(), stage: v.string() };
13
25
  const resource = { ...stage, fqn: v.string() };
@@ -32,60 +44,98 @@ const outputOf = (ctx: QueryCtx, args: { stack: string; stage: string }) =>
32
44
  .withIndex("by_stage", (q) => q.eq("stack", args.stack).eq("stage", args.stage))
33
45
  .unique();
34
46
 
35
- /** Stacks with at least one resource, in index order: one index read for each stack. */
36
- export const stacks = query({
47
+ /** The sorted union of two lists of names. */
48
+ const union = (a: readonly string[], b: readonly string[]) => [...new Set([...a, ...b])].sort();
49
+
50
+ /**
51
+ * The distinct names of one table in index order, with one index read for
52
+ * each name: `first(after)` is the first row whose name is above `after`.
53
+ */
54
+ const distinct = async (first: (after: string | undefined) => Promise<string | null>) => {
55
+ const names: string[] = [];
56
+ for (;;) {
57
+ const next = await first(names.at(-1));
58
+ if (next === null) return names;
59
+ names.push(next);
60
+ }
61
+ };
62
+
63
+ /** Stacks with at least one resource or one output, sorted. */
64
+ export const stacks = internalQuery({
37
65
  args: {},
38
66
  returns: v.array(v.string()),
39
- handler: async (ctx) => {
40
- const names: string[] = [];
41
- for (;;) {
42
- const last = names.at(-1);
43
- const next = await ctx.db
44
- .query("resources")
45
- .withIndex("by_fqn", (q) => (last === undefined ? q : q.gt("stack", last)))
46
- .first();
47
- if (next === null) return names;
48
- names.push(next.stack);
49
- }
50
- },
67
+ handler: async (ctx) =>
68
+ union(
69
+ await distinct(
70
+ async (after) =>
71
+ (
72
+ await ctx.db
73
+ .query("resources")
74
+ .withIndex("by_fqn", (q) => (after === undefined ? q : q.gt("stack", after)))
75
+ .first()
76
+ )?.stack ?? null,
77
+ ),
78
+ await distinct(
79
+ async (after) =>
80
+ (
81
+ await ctx.db
82
+ .query("outputs")
83
+ .withIndex("by_stage", (q) => (after === undefined ? q : q.gt("stack", after)))
84
+ .first()
85
+ )?.stack ?? null,
86
+ ),
87
+ ),
51
88
  });
52
89
 
53
- /** Stages of a stack with at least one resource, in index order. */
54
- export const stages = query({
90
+ /** Stages of a stack with at least one resource or one output, sorted. */
91
+ export const stages = internalQuery({
55
92
  args: { stack: v.string() },
56
93
  returns: v.array(v.string()),
57
- handler: async (ctx, args) => {
58
- const names: string[] = [];
59
- for (;;) {
60
- const last = names.at(-1);
61
- const next = await ctx.db
62
- .query("resources")
63
- .withIndex("by_fqn", (q) =>
64
- last === undefined
65
- ? q.eq("stack", args.stack)
66
- : q.eq("stack", args.stack).gt("stage", last),
67
- )
68
- .first();
69
- if (next === null) return names;
70
- names.push(next.stage);
71
- }
72
- },
94
+ handler: async (ctx, args) =>
95
+ union(
96
+ await distinct(
97
+ async (after) =>
98
+ (
99
+ await ctx.db
100
+ .query("resources")
101
+ .withIndex("by_fqn", (q) =>
102
+ after === undefined
103
+ ? q.eq("stack", args.stack)
104
+ : q.eq("stack", args.stack).gt("stage", after),
105
+ )
106
+ .first()
107
+ )?.stage ?? null,
108
+ ),
109
+ await distinct(
110
+ async (after) =>
111
+ (
112
+ await ctx.db
113
+ .query("outputs")
114
+ .withIndex("by_stage", (q) =>
115
+ after === undefined
116
+ ? q.eq("stack", args.stack)
117
+ : q.eq("stack", args.stack).gt("stage", after),
118
+ )
119
+ .first()
120
+ )?.stage ?? null,
121
+ ),
122
+ ),
73
123
  });
74
124
 
75
- export const list = query({
125
+ export const list = internalQuery({
76
126
  args: stage,
77
127
  returns: v.array(v.string()),
78
128
  handler: async (ctx, args) => (await rowsOf(ctx, args)).map((row) => row.fqn),
79
129
  });
80
130
 
81
- export const get = query({
131
+ export const get = internalQuery({
82
132
  args: resource,
83
133
  returns: v.union(v.string(), v.null()),
84
134
  handler: async (ctx, args) => (await rowOf(ctx, args))?.value ?? null,
85
135
  });
86
136
 
87
137
  /** Resources whose state has `status: "replaced"`. */
88
- export const replaced = query({
138
+ export const replaced = internalQuery({
89
139
  args: stage,
90
140
  returns: v.array(v.string()),
91
141
  handler: async (ctx, args) =>
@@ -102,7 +152,7 @@ export const replaced = query({
102
152
  }),
103
153
  });
104
154
 
105
- export const set = mutation({
155
+ export const set = internalMutation({
106
156
  args: { ...resource, value: v.string() },
107
157
  returns: v.null(),
108
158
  handler: async (ctx, args) => {
@@ -113,7 +163,7 @@ export const set = mutation({
113
163
  },
114
164
  });
115
165
 
116
- export const remove = mutation({
166
+ export const remove = internalMutation({
117
167
  args: resource,
118
168
  returns: v.null(),
119
169
  handler: async (ctx, args) => {
@@ -124,7 +174,7 @@ export const remove = mutation({
124
174
  });
125
175
 
126
176
  /** Deletes the resources and outputs of one stage, or of every stage of the stack. */
127
- export const removeStack = mutation({
177
+ export const removeStack = internalMutation({
128
178
  args: { stack: v.string(), stage: v.optional(v.string()) },
129
179
  returns: v.null(),
130
180
  handler: async (ctx, args) => {
@@ -151,13 +201,13 @@ export const removeStack = mutation({
151
201
  },
152
202
  });
153
203
 
154
- export const getOutput = query({
204
+ export const getOutput = internalQuery({
155
205
  args: stage,
156
206
  returns: v.union(v.string(), v.null()),
157
207
  handler: async (ctx, args) => (await outputOf(ctx, args))?.value ?? null,
158
208
  });
159
209
 
160
- export const setOutput = mutation({
210
+ export const setOutput = internalMutation({
161
211
  args: { ...stage, value: v.string() },
162
212
  returns: v.null(),
163
213
  handler: async (ctx, args) => {
@@ -0,0 +1,6 @@
1
+ // The wire version of the store: the `state:version` query answers it, and
2
+ // Convex.state() pushes this directory when the store of the team answers an
3
+ // older one or has no `version` yet. Raise it when a function changes in a way
4
+ // that an older client cannot use. Never rename or remove a function: an
5
+ // older client, and Samebase, call the store by these names.
6
+ export const STORE_VERSION = 1;
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "alchemy-state",
3
+ "private": true,
4
+ "type": "module",
5
+ "peerDependencies": {
6
+ "convex": "^1.46.0"
7
+ }
8
+ }
@@ -1,92 +0,0 @@
1
- /* eslint-disable */
2
- /**
3
- * Generated `ComponentApi` utility.
4
- *
5
- * THIS CODE IS AUTOMATICALLY GENERATED.
6
- *
7
- * To regenerate, run `npx convex dev`.
8
- * @module
9
- */
10
-
11
- import type { FunctionReference } from "convex/server";
12
-
13
- /**
14
- * A utility for referencing a Convex component's exposed API.
15
- *
16
- * Useful when expecting a parameter like `components.myComponent`.
17
- * Usage:
18
- * ```ts
19
- * async function myFunction(ctx: QueryCtx, component: ComponentApi) {
20
- * return ctx.runQuery(component.someFile.someQuery, { ...args });
21
- * }
22
- * ```
23
- */
24
- export type ComponentApi<Name extends string | undefined = string | undefined> =
25
- {
26
- state: {
27
- get: FunctionReference<
28
- "query",
29
- "internal",
30
- { fqn: string; stack: string; stage: string },
31
- string | null,
32
- Name
33
- >;
34
- getOutput: FunctionReference<
35
- "query",
36
- "internal",
37
- { stack: string; stage: string },
38
- string | null,
39
- Name
40
- >;
41
- list: FunctionReference<
42
- "query",
43
- "internal",
44
- { stack: string; stage: string },
45
- Array<string>,
46
- Name
47
- >;
48
- remove: FunctionReference<
49
- "mutation",
50
- "internal",
51
- { fqn: string; stack: string; stage: string },
52
- null,
53
- Name
54
- >;
55
- removeStack: FunctionReference<
56
- "mutation",
57
- "internal",
58
- { stack: string; stage?: string },
59
- null,
60
- Name
61
- >;
62
- replaced: FunctionReference<
63
- "query",
64
- "internal",
65
- { stack: string; stage: string },
66
- Array<string>,
67
- Name
68
- >;
69
- set: FunctionReference<
70
- "mutation",
71
- "internal",
72
- { fqn: string; stack: string; stage: string; value: string },
73
- null,
74
- Name
75
- >;
76
- setOutput: FunctionReference<
77
- "mutation",
78
- "internal",
79
- { stack: string; stage: string; value: string },
80
- null,
81
- Name
82
- >;
83
- stacks: FunctionReference<"query", "internal", {}, Array<string>, Name>;
84
- stages: FunctionReference<
85
- "query",
86
- "internal",
87
- { stack: string },
88
- Array<string>,
89
- Name
90
- >;
91
- };
92
- };
@@ -1,5 +0,0 @@
1
- // The Alchemy state store of a Convex app. Mount it with its default name:
2
- // `Convex.state()` calls it at the component path "alchemyState".
3
- import { defineComponent } from "convex/server";
4
-
5
- export default defineComponent("alchemyState");
File without changes