Skip to content

Commit 526a41a

Browse files
authored
feature: Added support for user parameters in sync rules. (#7)
* feature: Added support for user parameters in sync rules. * Updated a sync rule test to use both token and user parameters. * changed StreamingSyncRequest parameter's field to take a record of `any` instead of just strings. * Added changeset entry.
1 parent 72d8053 commit 526a41a

File tree

5 files changed

+31
-12
lines changed

5 files changed

+31
-12
lines changed

.changeset/witty-ducks-work.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@powersync/service-core': minor
3+
---
4+
5+
Added support for user parameters when making a StreamingSyncRequest.

packages/service-core/src/routes/socket-route.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ export const sync_stream_reactive: SocketRouteGenerator = (router) =>
3434

3535
const controller = new AbortController();
3636

37-
const syncParams: SyncParameters = normalizeTokenParameters(context.token_payload?.parameters ?? {});
37+
const syncParams: SyncParameters = normalizeTokenParameters(
38+
context.token_payload?.parameters ?? {},
39+
params.parameters ?? {}
40+
);
41+
3842
const storage = system.storage;
3943
// Sanity check before we start the stream
4044
const cp = await storage.getActiveCheckpoint();

packages/service-core/src/routes/sync-stream.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ export const syncStreamed: RouteGenerator = (router) =>
3030
}
3131

3232
const params: util.StreamingSyncRequest = payload.params;
33-
const syncParams: SyncParameters = normalizeTokenParameters(payload.context.token_payload!.parameters ?? {});
33+
const syncParams: SyncParameters = normalizeTokenParameters(
34+
payload.context.token_payload!.parameters ?? {},
35+
payload.params.parameters ?? {}
36+
);
3437

3538
const storage = system.storage;
3639
// Sanity check before we start the stream

packages/service-core/src/util/protocol-types.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,12 @@ export const StreamingSyncRequest = t.object({
8989
/**
9090
* Data is received in a serialized BSON Buffer
9191
*/
92-
binary_data: t.boolean.optional()
92+
binary_data: t.boolean.optional(),
93+
94+
/**
95+
* Client parameters to be passed to the sync rules.
96+
*/
97+
parameters: t.record(t.any).optional()
9398
});
9499

95100
export type StreamingSyncRequest = t.Decoded<typeof StreamingSyncRequest>;

packages/service-core/test/src/sync_rules.test.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,27 +100,29 @@ bucket_definitions:
100100
const rules = SqlSyncRules.fromYaml(`
101101
bucket_definitions:
102102
mybucket:
103-
parameters: SELECT token_parameters.user_id
103+
parameters: SELECT token_parameters.user_id, user_parameters.device_id
104104
data:
105-
- SELECT id, description FROM assets WHERE assets.user_id = bucket.user_id AND NOT assets.archived
105+
- SELECT id, description FROM assets WHERE assets.user_id = bucket.user_id AND assets.device_id = bucket.device_id AND NOT assets.archived
106106
`);
107107
const bucket = rules.bucket_descriptors[0];
108-
expect(bucket.bucket_parameters).toEqual(['user_id']);
108+
expect(bucket.bucket_parameters).toEqual(['user_id', 'device_id']);
109109
const param_query = bucket.global_parameter_queries[0];
110-
expect(param_query.bucket_parameters).toEqual(['user_id']);
111-
expect(rules.getStaticBucketIds(normalizeTokenParameters({ user_id: 'user1' }))).toEqual(['mybucket["user1"]']);
110+
expect(param_query.bucket_parameters).toEqual(['user_id', 'device_id']);
111+
expect(rules.getStaticBucketIds(normalizeTokenParameters({ user_id: 'user1' }, { device_id: 'device1' }))).toEqual([
112+
'mybucket["user1","device1"]'
113+
]);
112114

113115
const data_query = bucket.data_queries[0];
114-
expect(data_query.bucket_parameters).toEqual(['user_id']);
116+
expect(data_query.bucket_parameters).toEqual(['user_id', 'device_id']);
115117
expect(
116118
rules.evaluateRow({
117119
sourceTable: ASSETS,
118-
record: { id: 'asset1', description: 'test', user_id: 'user1' }
120+
record: { id: 'asset1', description: 'test', user_id: 'user1', device_id: 'device1' }
119121
})
120122
).toEqual([
121123
{
122124
ruleId: '1',
123-
bucket: 'mybucket["user1"]',
125+
bucket: 'mybucket["user1","device1"]',
124126
id: 'asset1',
125127
data: {
126128
id: 'asset1',
@@ -132,7 +134,7 @@ bucket_definitions:
132134
expect(
133135
rules.evaluateRow({
134136
sourceTable: ASSETS,
135-
record: { id: 'asset1', description: 'test', user_id: 'user1', archived: 1 }
137+
record: { id: 'asset1', description: 'test', user_id: 'user1', archived: 1, device_id: 'device1' }
136138
})
137139
).toEqual([]);
138140
});

0 commit comments

Comments
 (0)