Skip to content

Commit 72f34a3

Browse files
authored
[TS] Implement basic procedure calling (#3649)
# Description of Changes Implements `__call_procedure__` in the TS bindings and host. # Expected complexity level and risk 2 # 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 5113488 commit 72f34a3

File tree

19 files changed

+615
-369
lines changed

19 files changed

+615
-369
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { AlgebraicType, ProductType } from '../lib/algebraic_type';
2+
import type { ConnectionId } from '../lib/connection_id';
3+
import type { Identity } from '../lib/identity';
4+
import type { Timestamp } from '../lib/timestamp';
5+
import type { ParamsObj } from './reducers';
6+
import {
7+
MODULE_DEF,
8+
registerTypesRecursively,
9+
type UntypedSchemaDef,
10+
} from './schema';
11+
import type { Infer, InferTypeOfRow, TypeBuilder } from './type_builders';
12+
import { bsatnBaseSize } from './util';
13+
14+
export type ProcedureFn<
15+
S extends UntypedSchemaDef,
16+
Params extends ParamsObj,
17+
Ret extends TypeBuilder<any, any>,
18+
> = (ctx: ProcedureCtx<S>, args: InferTypeOfRow<Params>) => Infer<Ret>;
19+
20+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
21+
export interface ProcedureCtx<S extends UntypedSchemaDef> {
22+
readonly sender: Identity;
23+
readonly identity: Identity;
24+
readonly timestamp: Timestamp;
25+
readonly connectionId: ConnectionId | null;
26+
}
27+
28+
export function procedure<
29+
S extends UntypedSchemaDef,
30+
Params extends ParamsObj,
31+
Ret extends TypeBuilder<any, any>,
32+
>(name: string, params: Params, ret: Ret, fn: ProcedureFn<S, Params, Ret>) {
33+
const paramsType: ProductType = {
34+
elements: Object.entries(params).map(([n, c]) => ({
35+
name: n,
36+
algebraicType:
37+
'typeBuilder' in c ? c.typeBuilder.algebraicType : c.algebraicType,
38+
})),
39+
};
40+
const returnType = registerTypesRecursively(ret).algebraicType;
41+
42+
MODULE_DEF.miscExports.push({
43+
tag: 'Procedure',
44+
value: {
45+
name,
46+
params: paramsType,
47+
returnType,
48+
},
49+
});
50+
51+
PROCEDURES.push({
52+
fn,
53+
paramsType,
54+
returnType,
55+
returnTypeBaseSize: bsatnBaseSize(MODULE_DEF.typespace, returnType),
56+
});
57+
}
58+
59+
export const PROCEDURES: Array<{
60+
fn: ProcedureFn<any, any, any>;
61+
paramsType: ProductType;
62+
returnType: AlgebraicType;
63+
returnTypeBaseSize: number;
64+
}> = [];

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import {
4747
} from './views';
4848
import RawIndexDefV9 from './autogen/raw_index_def_v_9_type';
4949
import type { IndexOpts } from './indexes';
50+
import { procedure, type ProcedureFn } from './procedures';
5051

5152
export type TableNamesOf<S extends UntypedSchemaDef> =
5253
S['tables'][number]['name'];
@@ -547,6 +548,32 @@ class Schema<S extends UntypedSchemaDef> {
547548
// }
548549
// }
549550

551+
procedure<Params extends ParamsObj, Ret extends TypeBuilder<any, any>>(
552+
name: string,
553+
params: Params,
554+
ret: Ret,
555+
fn: ProcedureFn<S, Params, Ret>
556+
): ProcedureFn<S, Params, Ret>;
557+
procedure<Ret extends TypeBuilder<any, any>>(
558+
name: string,
559+
ret: Ret,
560+
fn: ProcedureFn<S, {}, Ret>
561+
): ProcedureFn<S, {}, Ret>;
562+
procedure<Params extends ParamsObj, Ret extends TypeBuilder<any, any>>(
563+
name: string,
564+
paramsOrRet: Ret | Params,
565+
retOrFn: ProcedureFn<S, {}, Ret> | Ret,
566+
maybeFn?: ProcedureFn<S, Params, Ret>
567+
): ProcedureFn<S, Params, Ret> {
568+
if (typeof retOrFn === 'function') {
569+
procedure(name, {}, paramsOrRet as Ret, retOrFn);
570+
return retOrFn;
571+
} else {
572+
procedure(name, paramsOrRet as Params, retOrFn, maybeFn!);
573+
return maybeFn!;
574+
}
575+
}
576+
550577
clientVisibilityFilter = {
551578
sql(filter: string): void {
552579
MODULE_DEF.rowLevelSecurity.push({ sql: filter });

0 commit comments

Comments
 (0)