Skip to content

Commit 7677b54

Browse files
authored
[TS] Export reducers, etc from a module (#4220)
# Description of Changes Haven't changed `schema()` to accept an object yet, maybe that's for a followup? Now everything exported from the module must be exported from the typescript module. # Expected complexity level and risk <!-- How complicated do you think these changes are? Grade on a scale from 1 to 5, where 1 is a trivial change, and 5 is a deep-reaching and complex change. This complexity rating applies not only to the complexity apparent in the diff, but also to its interactions with existing and future code. If you answered more than a 2, explain what is complex about the PR, and what other components it interacts with in potentially concerning ways. --> # Testing <!-- Describe any testing you've done, and any testing you'd like your reviewers to do, so that you're confident that all the changes work as expected! --> - [ ] <!-- maybe a test you want to do --> - [ ] <!-- maybe a test you want a reviewer to do, so they can check it off when they're satisfied. -->
1 parent 41d793f commit 7677b54

94 files changed

Lines changed: 1707 additions & 1219 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ rayon-core = "1.11.0"
255255
regex = "1"
256256
reqwest = { version = "0.12", features = ["stream", "json"] }
257257
rolldown = { git = "https://github.com/rolldown/rolldown.git", tag = "v1.0.0-beta.42" }
258+
rolldown_common = { git = "https://github.com/rolldown/rolldown.git", tag = "v1.0.0-beta.42" }
258259
rolldown_utils = { git = "https://github.com/rolldown/rolldown.git", tag = "v1.0.0-beta.42" }
259260
ron = "0.8"
260261
rusqlite = { version = "0.29.0", features = ["bundled", "column_decltype"] }

crates/bindings-typescript/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@
2020
"author": "Clockwork Labs",
2121
"type": "module",
2222
"sideEffects": [
23-
"./src/server/polyfills.ts",
24-
"./src/server/register_hooks.ts"
23+
"./src/server/polyfills.ts"
2524
],
2625
"scripts": {
2726
"build:js": "tsup",

crates/bindings-typescript/src/lib/autogen/function_visibility_type.ts

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/bindings-typescript/src/lib/table.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,20 @@ type ColList = ColId[];
4141
/**
4242
* Check if any column in the row has invalid metadata.
4343
*/
44-
type HasInvalidColumn<Row extends RowObj> = {
45-
[K in keyof Row]: Row[K] extends ColumnBuilder<any, any, infer M>
46-
? ValidateColumnMetadata<M> extends InvalidColumnMetadata<any>
47-
? true
48-
: false
49-
: false;
50-
}[keyof Row] extends false
51-
? false
52-
: true;
44+
type HasInvalidColumn<Row extends RowObj> =
45+
// this checks if Row exactly equals RowObj - if it does, we can't
46+
// do type-system-level checking, so just let it pass
47+
(<G>() => G extends Row ? 1 : 2) extends <G>() => G extends RowObj ? 1 : 2
48+
? false
49+
: {
50+
[K in keyof Row]: Row[K] extends ColumnBuilder<any, any, infer M>
51+
? ValidateColumnMetadata<M> extends InvalidColumnMetadata<any>
52+
? true
53+
: false
54+
: false;
55+
}[keyof Row] extends false
56+
? false
57+
: true;
5358

5459
/**
5560
* Extract the names of columns that have invalid metadata.

crates/bindings-typescript/src/sdk/client_api/index.ts

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/bindings-typescript/src/server/index.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
export * from '../lib/type_builders';
2-
export { schema, type InferSchema } from './schema';
2+
export { schema, type InferSchema, type ModuleExport } from './schema';
33
export { table } from '../lib/table';
44
export { SenderError, SpacetimeHostError, errors } from './errors';
5-
export { type Reducer, type ReducerCtx } from '../lib/reducers';
5+
export type { Reducer, ReducerCtx } from '../lib/reducers';
6+
export type { ReducerExport } from './reducers';
67
export { type DbView } from './db_view';
78
export * from './query';
8-
export type { ProcedureCtx, TransactionCtx } from './procedures';
9+
export type {
10+
ProcedureCtx,
11+
TransactionCtx,
12+
ProcedureExport,
13+
} from './procedures';
914
export { toCamelCase } from '../lib/util';
10-
export { type Uuid } from '../lib/uuid';
11-
export { type Random } from './rng';
15+
export type { Uuid } from '../lib/uuid';
16+
export type { Random } from './rng';
17+
export type { ViewExport, ViewCtx, AnonymousViewCtx } from './views';
1218

1319
import './polyfills'; // Ensure polyfills are loaded
14-
import './register_hooks'; // Ensure module hooks are registered

crates/bindings-typescript/src/server/procedures.ts

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,55 @@ import {
2020
import { bsatnBaseSize } from '../lib/util';
2121
import { Uuid } from '../lib/uuid';
2222
import { httpClient, type HttpClient } from './http_internal';
23+
import type { DbView } from './db_view';
2324
import { makeRandom, type Random } from './rng';
2425
import { callUserFunction, ReducerCtxImpl, sys } from './runtime';
25-
import type { SchemaInner } from './schema';
26+
import {
27+
exportContext,
28+
registerExport,
29+
type ModuleExport,
30+
type SchemaInner,
31+
} from './schema';
32+
33+
export type ProcedureExport<
34+
S extends UntypedSchemaDef,
35+
Params extends ParamsObj,
36+
Ret extends TypeBuilder<any, any>,
37+
> = ProcedureFn<S, Params, Ret> & ModuleExport;
38+
39+
export function makeProcedureExport<
40+
S extends UntypedSchemaDef,
41+
Params extends ParamsObj,
42+
Ret extends TypeBuilder<any, any>,
43+
>(
44+
ctx: SchemaInner,
45+
opts: ProcedureOpts | undefined,
46+
params: Params,
47+
ret: Ret,
48+
fn: ProcedureFn<S, Params, Ret>
49+
): ProcedureExport<S, Params, Ret> {
50+
const name = opts?.name;
51+
52+
const procedureExport: ProcedureExport<S, Params, Ret> = (...args) =>
53+
fn(...args);
54+
procedureExport[exportContext] = ctx;
55+
procedureExport[registerExport] = (ctx, exportName) => {
56+
registerProcedure(ctx, name ?? exportName, params, ret, fn);
57+
};
58+
59+
return procedureExport;
60+
}
2661

2762
export type ProcedureFn<
2863
S extends UntypedSchemaDef,
2964
Params extends ParamsObj,
3065
Ret extends TypeBuilder<any, any>,
3166
> = (ctx: ProcedureCtx<S>, args: InferTypeOfRow<Params>) => Infer<Ret>;
3267

68+
export interface ProcedureOpts {
69+
name: string;
70+
}
71+
3372
export interface ProcedureCtx<S extends UntypedSchemaDef> {
3473
readonly sender: Identity;
3574
readonly identity: Identity;
@@ -46,7 +85,7 @@ export interface ProcedureCtx<S extends UntypedSchemaDef> {
4685
export interface TransactionCtx<S extends UntypedSchemaDef>
4786
extends ReducerCtx<S> {}
4887

49-
export function procedure<
88+
function registerProcedure<
5089
S extends UntypedSchemaDef,
5190
Params extends ParamsObj,
5291
Ret extends TypeBuilder<any, any>,
@@ -98,7 +137,8 @@ export function callProcedure(
98137
sender: Identity,
99138
connectionId: ConnectionId | null,
100139
timestamp: Timestamp,
101-
argsBuf: Uint8Array
140+
argsBuf: Uint8Array,
141+
dbView: () => DbView<any>
102142
): Uint8Array {
103143
const { fn, deserializeArgs, serializeReturn, returnTypeBaseSize } =
104144
moduleCtx.procedures[id];
@@ -107,7 +147,8 @@ export function callProcedure(
107147
const ctx: ProcedureCtx<UntypedSchemaDef> = new ProcedureCtxImpl(
108148
sender,
109149
timestamp,
110-
connectionId
150+
connectionId,
151+
dbView
111152
);
112153

113154
const ret = callUserFunction(fn, ctx, args);
@@ -123,12 +164,16 @@ const ProcedureCtxImpl = class ProcedureCtx<S extends UntypedSchemaDef>
123164
#identity: Identity | undefined;
124165
#uuidCounter: { value: 0 } | undefined;
125166
#random: Random | undefined;
167+
#dbView: () => DbView<any>;
126168

127169
constructor(
128170
readonly sender: Identity,
129171
readonly timestamp: Timestamp,
130-
readonly connectionId: ConnectionId | null
131-
) {}
172+
readonly connectionId: ConnectionId | null,
173+
dbView: () => DbView<any>
174+
) {
175+
this.#dbView = dbView;
176+
}
132177

133178
get identity() {
134179
return (this.#identity ??= new Identity(sys.identity()));
@@ -150,7 +195,8 @@ const ProcedureCtxImpl = class ProcedureCtx<S extends UntypedSchemaDef>
150195
const ctx: TransactionCtx<UntypedSchemaDef> = new ReducerCtxImpl(
151196
this.sender,
152197
new Timestamp(timestamp),
153-
this.connectionId
198+
this.connectionId,
199+
this.#dbView()
154200
);
155201
return body(ctx);
156202
} catch (e) {

0 commit comments

Comments
 (0)