@risingwave/wavelet-sdk 0.1.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.
@@ -0,0 +1,15 @@
1
+ import type { WaveletClientOptions, ViewHandle, StreamHandle } from './types.js';
2
+ export declare class WaveletClient {
3
+ private options;
4
+ private baseUrl;
5
+ private wsBaseUrl;
6
+ private tokenProvider;
7
+ constructor(options: WaveletClientOptions);
8
+ view<T = Record<string, unknown>>(name: string): ViewHandle<T>;
9
+ stream<T = Record<string, unknown>>(name: string): StreamHandle<T>;
10
+ private getView;
11
+ private subscribeView;
12
+ private emitEvent;
13
+ private emitBatch;
14
+ }
15
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,UAAU,EAAE,YAAY,EAAwC,MAAM,YAAY,CAAA;AAGtH,qBAAa,aAAa;IAKZ,OAAO,CAAC,OAAO;IAJ3B,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,aAAa,CAAgC;gBAEjC,OAAO,EAAE,oBAAoB;IAmBjD,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC;IAO9D,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC;YAOpD,OAAO;IA0BrB,OAAO,CAAC,aAAa;YAyEP,SAAS;YAkBT,SAAS;CAiBxB"}
package/dist/client.js ADDED
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WaveletClient = void 0;
4
+ const types_js_1 = require("./types.js");
5
+ class WaveletClient {
6
+ options;
7
+ baseUrl;
8
+ wsBaseUrl;
9
+ tokenProvider;
10
+ constructor(options) {
11
+ this.options = options;
12
+ // Normalize URLs
13
+ this.baseUrl = options.url.replace(/\/$/, '').replace(/^ws/, 'http');
14
+ this.wsBaseUrl = options.url.replace(/\/$/, '').replace(/^http/, 'ws');
15
+ if (typeof options.token === 'function') {
16
+ const fn = options.token;
17
+ this.tokenProvider = async () => {
18
+ const t = fn();
19
+ return t instanceof Promise ? t : t;
20
+ };
21
+ }
22
+ else if (typeof options.token === 'string') {
23
+ const t = options.token;
24
+ this.tokenProvider = async () => t;
25
+ }
26
+ else {
27
+ this.tokenProvider = null;
28
+ }
29
+ }
30
+ view(name) {
31
+ return {
32
+ get: (params) => this.getView(name, params),
33
+ subscribe: (handlers) => this.subscribeView(name, handlers),
34
+ };
35
+ }
36
+ stream(name) {
37
+ return {
38
+ emit: (data) => this.emitEvent(name, data),
39
+ emitBatch: (data) => this.emitBatch(name, data),
40
+ };
41
+ }
42
+ async getView(name, params) {
43
+ const url = new URL(`${this.baseUrl}/v1/views/${name}`);
44
+ if (params) {
45
+ for (const [k, v] of Object.entries(params)) {
46
+ url.searchParams.set(k, v);
47
+ }
48
+ }
49
+ const headers = { 'Content-Type': 'application/json' };
50
+ if (this.tokenProvider) {
51
+ headers['Authorization'] = `Bearer ${await this.tokenProvider()}`;
52
+ }
53
+ const res = await fetch(url.toString(), { headers });
54
+ if (!res.ok) {
55
+ const body = await res.json().catch(() => ({}));
56
+ if (res.status === 404)
57
+ throw new types_js_1.WaveletError(body.error ?? `View '${name}' not found`, 'VIEW_NOT_FOUND');
58
+ if (res.status === 401)
59
+ throw new types_js_1.WaveletError(body.error ?? 'Authentication required', 'AUTH_ERROR');
60
+ throw new types_js_1.WaveletError(body.error ?? `Server error: ${res.status}`, 'SERVER_ERROR');
61
+ }
62
+ const data = await res.json();
63
+ return data.rows;
64
+ }
65
+ subscribeView(name, handlers) {
66
+ let ws = null;
67
+ let closed = false;
68
+ let reconnectAttempt = 0;
69
+ const maxReconnectDelay = 30000;
70
+ let lastCursor = null;
71
+ const connect = async () => {
72
+ if (closed)
73
+ return;
74
+ let url = `${this.wsBaseUrl}/subscribe/${name}`;
75
+ if (this.tokenProvider) {
76
+ const token = await this.tokenProvider();
77
+ url += `?token=${encodeURIComponent(token)}`;
78
+ }
79
+ if (lastCursor) {
80
+ url += `${url.includes('?') ? '&' : '?'}cursor=${encodeURIComponent(lastCursor)}`;
81
+ }
82
+ ws = new WebSocket(url);
83
+ ws.onopen = () => {
84
+ reconnectAttempt = 0;
85
+ };
86
+ ws.onmessage = (event) => {
87
+ try {
88
+ const msg = JSON.parse(typeof event.data === 'string' ? event.data : '');
89
+ if (msg.type === 'diff') {
90
+ lastCursor = msg.cursor;
91
+ handlers.onData({
92
+ cursor: msg.cursor,
93
+ inserted: msg.inserted ?? [],
94
+ updated: msg.updated ?? [],
95
+ deleted: msg.deleted ?? [],
96
+ });
97
+ }
98
+ }
99
+ catch (err) {
100
+ handlers.onError?.(new types_js_1.WaveletError(err.message, 'SERVER_ERROR'));
101
+ }
102
+ };
103
+ ws.onerror = () => {
104
+ // onclose will fire next
105
+ };
106
+ ws.onclose = (event) => {
107
+ if (closed)
108
+ return;
109
+ if (event.code === 4000) {
110
+ // Server rejected connection (auth error, view not found)
111
+ handlers.onError?.(new types_js_1.WaveletError(event.reason, 'AUTH_ERROR'));
112
+ return;
113
+ }
114
+ // Reconnect with exponential backoff
115
+ const delay = Math.min(1000 * Math.pow(2, reconnectAttempt), maxReconnectDelay);
116
+ reconnectAttempt++;
117
+ setTimeout(() => {
118
+ handlers.onReconnect?.();
119
+ connect();
120
+ }, delay);
121
+ };
122
+ };
123
+ connect();
124
+ return () => {
125
+ closed = true;
126
+ ws?.close();
127
+ };
128
+ }
129
+ async emitEvent(streamName, data) {
130
+ const headers = { 'Content-Type': 'application/json' };
131
+ if (this.tokenProvider) {
132
+ headers['Authorization'] = `Bearer ${await this.tokenProvider()}`;
133
+ }
134
+ const res = await fetch(`${this.baseUrl}/v1/streams/${streamName}`, {
135
+ method: 'POST',
136
+ headers,
137
+ body: JSON.stringify(data),
138
+ });
139
+ if (!res.ok) {
140
+ const body = await res.json().catch(() => ({}));
141
+ throw new types_js_1.WaveletError(body.error ?? `Failed to emit to '${streamName}'`, 'SERVER_ERROR');
142
+ }
143
+ }
144
+ async emitBatch(streamName, data) {
145
+ const headers = { 'Content-Type': 'application/json' };
146
+ if (this.tokenProvider) {
147
+ headers['Authorization'] = `Bearer ${await this.tokenProvider()}`;
148
+ }
149
+ const res = await fetch(`${this.baseUrl}/v1/streams/${streamName}/batch`, {
150
+ method: 'POST',
151
+ headers,
152
+ body: JSON.stringify(data),
153
+ });
154
+ if (!res.ok) {
155
+ const body = await res.json().catch(() => ({}));
156
+ throw new types_js_1.WaveletError(body.error ?? `Failed to batch emit to '${streamName}'`, 'SERVER_ERROR');
157
+ }
158
+ }
159
+ }
160
+ exports.WaveletClient = WaveletClient;
161
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { WaveletClient } from './client.js';
2
+ export type { WaveletClientOptions, ViewHandle, StreamHandle, Diff, Unsubscribe } from './types.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WaveletClient = void 0;
4
+ var client_js_1 = require("./client.js");
5
+ Object.defineProperty(exports, "WaveletClient", { enumerable: true, get: function () { return client_js_1.WaveletClient; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,yCAA2C;AAAlC,0GAAA,aAAa,OAAA"}
@@ -0,0 +1,12 @@
1
+ import { WaveletClient } from './client.js';
2
+ import type { WaveletClientOptions } from './types.js';
3
+ import { WaveletError } from './types.js';
4
+ export declare function initWavelet(options: WaveletClientOptions): void;
5
+ export declare function getClient(): WaveletClient;
6
+ export interface UseWaveletResult<T> {
7
+ data: T[];
8
+ isLoading: boolean;
9
+ error: WaveletError | null;
10
+ }
11
+ export declare function useWavelet<T = Record<string, unknown>>(viewName: string, params?: Record<string, string>): UseWaveletResult<T>;
12
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,KAAK,EAAQ,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAIzC,wBAAgB,WAAW,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAE/D;AAED,wBAAgB,SAAS,IAAI,aAAa,CAQzC;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,IAAI,EAAE,CAAC,EAAE,CAAA;IACT,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,YAAY,GAAG,IAAI,CAAA;CAC3B;AAED,wBAAgB,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpD,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,gBAAgB,CAAC,CAAC,CAAC,CAyDrB"}
package/dist/react.js ADDED
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initWavelet = initWavelet;
4
+ exports.getClient = getClient;
5
+ exports.useWavelet = useWavelet;
6
+ const react_1 = require("react");
7
+ const client_js_1 = require("./client.js");
8
+ const types_js_1 = require("./types.js");
9
+ let globalClient = null;
10
+ function initWavelet(options) {
11
+ globalClient = new client_js_1.WaveletClient(options);
12
+ }
13
+ function getClient() {
14
+ if (!globalClient) {
15
+ throw new types_js_1.WaveletError('Wavelet client not initialized. Call initWavelet({ url: "..." }) first.', 'CONNECTION_ERROR');
16
+ }
17
+ return globalClient;
18
+ }
19
+ function useWavelet(viewName, params) {
20
+ const [data, setData] = (0, react_1.useState)([]);
21
+ const [isLoading, setIsLoading] = (0, react_1.useState)(true);
22
+ const [error, setError] = (0, react_1.useState)(null);
23
+ const dataRef = (0, react_1.useRef)([]);
24
+ (0, react_1.useEffect)(() => {
25
+ const client = getClient();
26
+ let cancelled = false;
27
+ // Initial fetch
28
+ client.view(viewName).get(params).then((rows) => {
29
+ if (cancelled)
30
+ return;
31
+ dataRef.current = rows;
32
+ setData(rows);
33
+ setIsLoading(false);
34
+ }).catch((err) => {
35
+ if (cancelled)
36
+ return;
37
+ setError(err instanceof types_js_1.WaveletError ? err : new types_js_1.WaveletError(err.message, 'SERVER_ERROR'));
38
+ setIsLoading(false);
39
+ });
40
+ // Subscribe to updates
41
+ const unsub = client.view(viewName).subscribe({
42
+ onData: (diff) => {
43
+ if (cancelled)
44
+ return;
45
+ // Simple merge: this is a naive approach, replace with key-based merge in production
46
+ let current = [...dataRef.current];
47
+ // Remove deleted rows (by reference equality on all fields)
48
+ if (diff.deleted.length > 0) {
49
+ const deletedJson = new Set(diff.deleted.map(r => JSON.stringify(r)));
50
+ current = current.filter(r => !deletedJson.has(JSON.stringify(r)));
51
+ }
52
+ // Add inserted rows
53
+ current.push(...diff.inserted);
54
+ // For updates: remove old, add new (updates come as pairs)
55
+ current.push(...diff.updated);
56
+ dataRef.current = current;
57
+ setData(current);
58
+ },
59
+ onError: (err) => {
60
+ if (cancelled)
61
+ return;
62
+ setError(err);
63
+ },
64
+ });
65
+ return () => {
66
+ cancelled = true;
67
+ unsub();
68
+ };
69
+ }, [viewName, JSON.stringify(params)]);
70
+ return { data, isLoading, error };
71
+ }
72
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export interface WaveletClientOptions {
2
+ url: string;
3
+ token?: string | (() => string | Promise<string>);
4
+ }
5
+ export interface Diff<T = Record<string, unknown>> {
6
+ cursor: string;
7
+ inserted: T[];
8
+ updated: T[];
9
+ deleted: T[];
10
+ }
11
+ export interface ViewHandle<T = Record<string, unknown>> {
12
+ get(params?: Record<string, string>): Promise<T[]>;
13
+ subscribe(handlers: SubscribeHandlers<T>): Unsubscribe;
14
+ }
15
+ export interface StreamHandle<T = Record<string, unknown>> {
16
+ emit(data: T): Promise<void>;
17
+ emitBatch(data: T[]): Promise<void>;
18
+ }
19
+ export interface SubscribeHandlers<T> {
20
+ onData: (diff: Diff<T>) => void;
21
+ onError?: (error: WaveletError) => void;
22
+ onReconnect?: () => void;
23
+ }
24
+ export type Unsubscribe = () => void;
25
+ export type WaveletErrorCode = 'AUTH_ERROR' | 'VIEW_NOT_FOUND' | 'CONNECTION_ERROR' | 'SERVER_ERROR';
26
+ export declare class WaveletError extends Error {
27
+ readonly code: WaveletErrorCode;
28
+ constructor(message: string, code: WaveletErrorCode);
29
+ }
30
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;CAClD;AAED,MAAM,WAAW,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC/C,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,CAAC,EAAE,CAAA;IACb,OAAO,EAAE,CAAC,EAAE,CAAA;IACZ,OAAO,EAAE,CAAC,EAAE,CAAA;CACb;AAED,MAAM,WAAW,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACrD,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAA;IAClD,SAAS,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,WAAW,CAAA;CACvD;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACvD,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5B,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACpC;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IAC/B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;IACvC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;CACzB;AAED,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAA;AAEpC,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,cAAc,CAAA;AAEpG,qBAAa,YAAa,SAAQ,KAAK;aAGnB,IAAI,EAAE,gBAAgB;gBADtC,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,gBAAgB;CAKzC"}
package/dist/types.js ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WaveletError = void 0;
4
+ class WaveletError extends Error {
5
+ code;
6
+ constructor(message, code) {
7
+ super(message);
8
+ this.code = code;
9
+ this.name = 'WaveletError';
10
+ }
11
+ }
12
+ exports.WaveletError = WaveletError;
13
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAgCA,MAAa,YAAa,SAAQ,KAAK;IAGnB;IAFlB,YACE,OAAe,EACC,IAAsB;QAEtC,KAAK,CAAC,OAAO,CAAC,CAAA;QAFE,SAAI,GAAJ,IAAI,CAAkB;QAGtC,IAAI,CAAC,IAAI,GAAG,cAAc,CAAA;IAC5B,CAAC;CACF;AARD,oCAQC"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@risingwave/wavelet-sdk",
3
+ "version": "0.1.0",
4
+ "description": "Wavelet TypeScript SDK - subscribe to computed results",
5
+ "homepage": "https://github.com/risingwavelabs/wavelet",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/risingwavelabs/wavelet.git",
9
+ "directory": "packages/sdk"
10
+ },
11
+ "main": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js"
17
+ },
18
+ "./react": {
19
+ "types": "./dist/react.d.ts",
20
+ "import": "./dist/react.js"
21
+ }
22
+ },
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "scripts": {
27
+ "build": "tsc",
28
+ "dev": "tsc --watch"
29
+ },
30
+ "peerDependencies": {
31
+ "react": ">=18"
32
+ },
33
+ "peerDependenciesMeta": {
34
+ "react": {
35
+ "optional": true
36
+ }
37
+ },
38
+ "license": "Apache-2.0",
39
+ "devDependencies": {
40
+ "@types/react": "^19.2.14"
41
+ }
42
+ }