@blinkdotnew/sdk 0.6.0 → 0.6.1
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.
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +70 -9
- package/dist/index.mjs +70 -9
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -681,6 +681,7 @@ declare class BlinkRealtimeChannel implements RealtimeChannel {
|
|
|
681
681
|
private isSubscribed;
|
|
682
682
|
private reconnectTimer;
|
|
683
683
|
private heartbeatTimer;
|
|
684
|
+
private reconnectAttempts;
|
|
684
685
|
constructor(channelName: string, httpClient: HttpClient, projectId: string);
|
|
685
686
|
subscribe(options?: {
|
|
686
687
|
userId?: string;
|
|
@@ -709,6 +710,7 @@ declare class BlinkRealtimeImpl implements BlinkRealtime {
|
|
|
709
710
|
private httpClient;
|
|
710
711
|
private projectId;
|
|
711
712
|
private channels;
|
|
713
|
+
private handlers;
|
|
712
714
|
constructor(httpClient: HttpClient, projectId: string);
|
|
713
715
|
channel(name: string): RealtimeChannel;
|
|
714
716
|
subscribe(channelName: string, callback: (message: RealtimeMessage) => void, options?: RealtimeSubscribeOptions): Promise<() => void>;
|
package/dist/index.d.ts
CHANGED
|
@@ -681,6 +681,7 @@ declare class BlinkRealtimeChannel implements RealtimeChannel {
|
|
|
681
681
|
private isSubscribed;
|
|
682
682
|
private reconnectTimer;
|
|
683
683
|
private heartbeatTimer;
|
|
684
|
+
private reconnectAttempts;
|
|
684
685
|
constructor(channelName: string, httpClient: HttpClient, projectId: string);
|
|
685
686
|
subscribe(options?: {
|
|
686
687
|
userId?: string;
|
|
@@ -709,6 +710,7 @@ declare class BlinkRealtimeImpl implements BlinkRealtime {
|
|
|
709
710
|
private httpClient;
|
|
710
711
|
private projectId;
|
|
711
712
|
private channels;
|
|
713
|
+
private handlers;
|
|
712
714
|
constructor(httpClient: HttpClient, projectId: string);
|
|
713
715
|
channel(name: string): RealtimeChannel;
|
|
714
716
|
subscribe(channelName: string, callback: (message: RealtimeMessage) => void, options?: RealtimeSubscribeOptions): Promise<() => void>;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
4
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
5
|
+
}) : x)(function(x) {
|
|
6
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
7
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
8
|
+
});
|
|
9
|
+
|
|
3
10
|
// ../core/src/types.ts
|
|
4
11
|
var BlinkError = class extends Error {
|
|
5
12
|
constructor(message, code, status, details) {
|
|
@@ -2474,6 +2481,17 @@ var BlinkDataImpl = class {
|
|
|
2474
2481
|
};
|
|
2475
2482
|
|
|
2476
2483
|
// src/realtime.ts
|
|
2484
|
+
var getWebSocketClass = () => {
|
|
2485
|
+
if (typeof WebSocket !== "undefined") {
|
|
2486
|
+
return WebSocket;
|
|
2487
|
+
}
|
|
2488
|
+
try {
|
|
2489
|
+
const WS = __require("ws");
|
|
2490
|
+
return WS;
|
|
2491
|
+
} catch (error) {
|
|
2492
|
+
throw new BlinkRealtimeError('WebSocket is not available. Install "ws" package for Node.js environments.');
|
|
2493
|
+
}
|
|
2494
|
+
};
|
|
2477
2495
|
var BlinkRealtimeChannel = class {
|
|
2478
2496
|
constructor(channelName, httpClient, projectId) {
|
|
2479
2497
|
this.channelName = channelName;
|
|
@@ -2486,6 +2504,7 @@ var BlinkRealtimeChannel = class {
|
|
|
2486
2504
|
isSubscribed = false;
|
|
2487
2505
|
reconnectTimer = null;
|
|
2488
2506
|
heartbeatTimer = null;
|
|
2507
|
+
reconnectAttempts = 0;
|
|
2489
2508
|
async subscribe(options = {}) {
|
|
2490
2509
|
if (this.isSubscribed) {
|
|
2491
2510
|
return;
|
|
@@ -2576,7 +2595,9 @@ var BlinkRealtimeChannel = class {
|
|
|
2576
2595
|
channel: this.channelName,
|
|
2577
2596
|
limit: options.limit,
|
|
2578
2597
|
start: options.after,
|
|
2598
|
+
// after = start from this ID onwards
|
|
2579
2599
|
end: options.before
|
|
2600
|
+
// before = end at this ID
|
|
2580
2601
|
});
|
|
2581
2602
|
return response.data.messages;
|
|
2582
2603
|
} catch (error) {
|
|
@@ -2586,16 +2607,22 @@ var BlinkRealtimeChannel = class {
|
|
|
2586
2607
|
}
|
|
2587
2608
|
}
|
|
2588
2609
|
async connectWebSocket() {
|
|
2589
|
-
if (this.websocket && this.websocket.readyState ===
|
|
2610
|
+
if (this.websocket && this.websocket.readyState === 1) {
|
|
2590
2611
|
return;
|
|
2591
2612
|
}
|
|
2592
2613
|
return new Promise((resolve, reject) => {
|
|
2593
2614
|
try {
|
|
2594
2615
|
const baseUrl = this.httpClient.projectId.includes("localhost") ? "ws://localhost:3000" : "wss://core.blink.new";
|
|
2595
2616
|
const wsUrl = `${baseUrl}?project_id=${this.projectId}`;
|
|
2596
|
-
|
|
2617
|
+
const WSClass = getWebSocketClass();
|
|
2618
|
+
this.websocket = new WSClass(wsUrl);
|
|
2619
|
+
if (!this.websocket) {
|
|
2620
|
+
reject(new BlinkRealtimeError("Failed to create WebSocket instance"));
|
|
2621
|
+
return;
|
|
2622
|
+
}
|
|
2597
2623
|
this.websocket.onopen = () => {
|
|
2598
2624
|
console.log(`\u{1F517} Connected to realtime for project ${this.projectId}`);
|
|
2625
|
+
this.reconnectAttempts = 0;
|
|
2599
2626
|
resolve();
|
|
2600
2627
|
};
|
|
2601
2628
|
this.websocket.onmessage = (event) => {
|
|
@@ -2616,7 +2643,7 @@ var BlinkRealtimeChannel = class {
|
|
|
2616
2643
|
reject(new BlinkRealtimeError("WebSocket connection failed"));
|
|
2617
2644
|
};
|
|
2618
2645
|
setTimeout(() => {
|
|
2619
|
-
if (this.websocket?.readyState !==
|
|
2646
|
+
if (this.websocket?.readyState !== 1) {
|
|
2620
2647
|
reject(new BlinkRealtimeError("WebSocket connection timeout"));
|
|
2621
2648
|
}
|
|
2622
2649
|
}, 5e3);
|
|
@@ -2664,8 +2691,8 @@ var BlinkRealtimeChannel = class {
|
|
|
2664
2691
|
if (this.heartbeatTimer) {
|
|
2665
2692
|
clearInterval(this.heartbeatTimer);
|
|
2666
2693
|
}
|
|
2667
|
-
this.heartbeatTimer =
|
|
2668
|
-
if (this.websocket && this.websocket.readyState ===
|
|
2694
|
+
this.heartbeatTimer = globalThis.setInterval(() => {
|
|
2695
|
+
if (this.websocket && this.websocket.readyState === 1) {
|
|
2669
2696
|
this.websocket.send(JSON.stringify({ type: "ping", payload: {} }));
|
|
2670
2697
|
}
|
|
2671
2698
|
}, 25e3);
|
|
@@ -2674,7 +2701,12 @@ var BlinkRealtimeChannel = class {
|
|
|
2674
2701
|
if (this.reconnectTimer) {
|
|
2675
2702
|
clearTimeout(this.reconnectTimer);
|
|
2676
2703
|
}
|
|
2677
|
-
this.
|
|
2704
|
+
this.reconnectAttempts++;
|
|
2705
|
+
const baseDelay = Math.min(3e4, Math.pow(2, this.reconnectAttempts) * 1e3);
|
|
2706
|
+
const jitter = Math.random() * 1e3;
|
|
2707
|
+
const delay = baseDelay + jitter;
|
|
2708
|
+
console.log(`\u{1F504} Scheduling reconnect attempt ${this.reconnectAttempts} in ${Math.round(delay)}ms`);
|
|
2709
|
+
this.reconnectTimer = globalThis.setTimeout(async () => {
|
|
2678
2710
|
if (this.isSubscribed) {
|
|
2679
2711
|
try {
|
|
2680
2712
|
await this.connectWebSocket();
|
|
@@ -2693,7 +2725,7 @@ var BlinkRealtimeChannel = class {
|
|
|
2693
2725
|
this.scheduleReconnect();
|
|
2694
2726
|
}
|
|
2695
2727
|
}
|
|
2696
|
-
},
|
|
2728
|
+
}, delay);
|
|
2697
2729
|
}
|
|
2698
2730
|
cleanup() {
|
|
2699
2731
|
this.isSubscribed = false;
|
|
@@ -2719,6 +2751,7 @@ var BlinkRealtimeImpl = class {
|
|
|
2719
2751
|
this.projectId = projectId;
|
|
2720
2752
|
}
|
|
2721
2753
|
channels = /* @__PURE__ */ new Map();
|
|
2754
|
+
handlers = {};
|
|
2722
2755
|
channel(name) {
|
|
2723
2756
|
if (!this.channels.has(name)) {
|
|
2724
2757
|
this.channels.set(name, new BlinkRealtimeChannel(name, this.httpClient, this.projectId));
|
|
@@ -2728,7 +2761,21 @@ var BlinkRealtimeImpl = class {
|
|
|
2728
2761
|
async subscribe(channelName, callback, options = {}) {
|
|
2729
2762
|
const channel = this.channel(channelName);
|
|
2730
2763
|
await channel.subscribe(options);
|
|
2731
|
-
|
|
2764
|
+
const state = this.handlers[channelName] ??= {
|
|
2765
|
+
msgHandlers: /* @__PURE__ */ new Set(),
|
|
2766
|
+
presHandlers: /* @__PURE__ */ new Set(),
|
|
2767
|
+
subscribed: true
|
|
2768
|
+
};
|
|
2769
|
+
state.msgHandlers.add(callback);
|
|
2770
|
+
const messageUnsub = channel.onMessage(callback);
|
|
2771
|
+
return () => {
|
|
2772
|
+
messageUnsub();
|
|
2773
|
+
state.msgHandlers.delete(callback);
|
|
2774
|
+
if (state.msgHandlers.size === 0 && state.presHandlers.size === 0) {
|
|
2775
|
+
channel.unsubscribe();
|
|
2776
|
+
delete this.handlers[channelName];
|
|
2777
|
+
}
|
|
2778
|
+
};
|
|
2732
2779
|
}
|
|
2733
2780
|
async publish(channelName, type, data, options = {}) {
|
|
2734
2781
|
const channel = this.channel(channelName);
|
|
@@ -2740,7 +2787,21 @@ var BlinkRealtimeImpl = class {
|
|
|
2740
2787
|
}
|
|
2741
2788
|
onPresence(channelName, callback) {
|
|
2742
2789
|
const channel = this.channel(channelName);
|
|
2743
|
-
|
|
2790
|
+
const state = this.handlers[channelName] ??= {
|
|
2791
|
+
msgHandlers: /* @__PURE__ */ new Set(),
|
|
2792
|
+
presHandlers: /* @__PURE__ */ new Set(),
|
|
2793
|
+
subscribed: false
|
|
2794
|
+
};
|
|
2795
|
+
state.presHandlers.add(callback);
|
|
2796
|
+
const presenceUnsub = channel.onPresence(callback);
|
|
2797
|
+
return () => {
|
|
2798
|
+
presenceUnsub();
|
|
2799
|
+
state.presHandlers.delete(callback);
|
|
2800
|
+
if (state.msgHandlers.size === 0 && state.presHandlers.size === 0) {
|
|
2801
|
+
channel.unsubscribe();
|
|
2802
|
+
delete this.handlers[channelName];
|
|
2803
|
+
}
|
|
2804
|
+
};
|
|
2744
2805
|
}
|
|
2745
2806
|
};
|
|
2746
2807
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
1
8
|
// ../core/src/types.ts
|
|
2
9
|
var BlinkError = class extends Error {
|
|
3
10
|
constructor(message, code, status, details) {
|
|
@@ -2472,6 +2479,17 @@ var BlinkDataImpl = class {
|
|
|
2472
2479
|
};
|
|
2473
2480
|
|
|
2474
2481
|
// src/realtime.ts
|
|
2482
|
+
var getWebSocketClass = () => {
|
|
2483
|
+
if (typeof WebSocket !== "undefined") {
|
|
2484
|
+
return WebSocket;
|
|
2485
|
+
}
|
|
2486
|
+
try {
|
|
2487
|
+
const WS = __require("ws");
|
|
2488
|
+
return WS;
|
|
2489
|
+
} catch (error) {
|
|
2490
|
+
throw new BlinkRealtimeError('WebSocket is not available. Install "ws" package for Node.js environments.');
|
|
2491
|
+
}
|
|
2492
|
+
};
|
|
2475
2493
|
var BlinkRealtimeChannel = class {
|
|
2476
2494
|
constructor(channelName, httpClient, projectId) {
|
|
2477
2495
|
this.channelName = channelName;
|
|
@@ -2484,6 +2502,7 @@ var BlinkRealtimeChannel = class {
|
|
|
2484
2502
|
isSubscribed = false;
|
|
2485
2503
|
reconnectTimer = null;
|
|
2486
2504
|
heartbeatTimer = null;
|
|
2505
|
+
reconnectAttempts = 0;
|
|
2487
2506
|
async subscribe(options = {}) {
|
|
2488
2507
|
if (this.isSubscribed) {
|
|
2489
2508
|
return;
|
|
@@ -2574,7 +2593,9 @@ var BlinkRealtimeChannel = class {
|
|
|
2574
2593
|
channel: this.channelName,
|
|
2575
2594
|
limit: options.limit,
|
|
2576
2595
|
start: options.after,
|
|
2596
|
+
// after = start from this ID onwards
|
|
2577
2597
|
end: options.before
|
|
2598
|
+
// before = end at this ID
|
|
2578
2599
|
});
|
|
2579
2600
|
return response.data.messages;
|
|
2580
2601
|
} catch (error) {
|
|
@@ -2584,16 +2605,22 @@ var BlinkRealtimeChannel = class {
|
|
|
2584
2605
|
}
|
|
2585
2606
|
}
|
|
2586
2607
|
async connectWebSocket() {
|
|
2587
|
-
if (this.websocket && this.websocket.readyState ===
|
|
2608
|
+
if (this.websocket && this.websocket.readyState === 1) {
|
|
2588
2609
|
return;
|
|
2589
2610
|
}
|
|
2590
2611
|
return new Promise((resolve, reject) => {
|
|
2591
2612
|
try {
|
|
2592
2613
|
const baseUrl = this.httpClient.projectId.includes("localhost") ? "ws://localhost:3000" : "wss://core.blink.new";
|
|
2593
2614
|
const wsUrl = `${baseUrl}?project_id=${this.projectId}`;
|
|
2594
|
-
|
|
2615
|
+
const WSClass = getWebSocketClass();
|
|
2616
|
+
this.websocket = new WSClass(wsUrl);
|
|
2617
|
+
if (!this.websocket) {
|
|
2618
|
+
reject(new BlinkRealtimeError("Failed to create WebSocket instance"));
|
|
2619
|
+
return;
|
|
2620
|
+
}
|
|
2595
2621
|
this.websocket.onopen = () => {
|
|
2596
2622
|
console.log(`\u{1F517} Connected to realtime for project ${this.projectId}`);
|
|
2623
|
+
this.reconnectAttempts = 0;
|
|
2597
2624
|
resolve();
|
|
2598
2625
|
};
|
|
2599
2626
|
this.websocket.onmessage = (event) => {
|
|
@@ -2614,7 +2641,7 @@ var BlinkRealtimeChannel = class {
|
|
|
2614
2641
|
reject(new BlinkRealtimeError("WebSocket connection failed"));
|
|
2615
2642
|
};
|
|
2616
2643
|
setTimeout(() => {
|
|
2617
|
-
if (this.websocket?.readyState !==
|
|
2644
|
+
if (this.websocket?.readyState !== 1) {
|
|
2618
2645
|
reject(new BlinkRealtimeError("WebSocket connection timeout"));
|
|
2619
2646
|
}
|
|
2620
2647
|
}, 5e3);
|
|
@@ -2662,8 +2689,8 @@ var BlinkRealtimeChannel = class {
|
|
|
2662
2689
|
if (this.heartbeatTimer) {
|
|
2663
2690
|
clearInterval(this.heartbeatTimer);
|
|
2664
2691
|
}
|
|
2665
|
-
this.heartbeatTimer =
|
|
2666
|
-
if (this.websocket && this.websocket.readyState ===
|
|
2692
|
+
this.heartbeatTimer = globalThis.setInterval(() => {
|
|
2693
|
+
if (this.websocket && this.websocket.readyState === 1) {
|
|
2667
2694
|
this.websocket.send(JSON.stringify({ type: "ping", payload: {} }));
|
|
2668
2695
|
}
|
|
2669
2696
|
}, 25e3);
|
|
@@ -2672,7 +2699,12 @@ var BlinkRealtimeChannel = class {
|
|
|
2672
2699
|
if (this.reconnectTimer) {
|
|
2673
2700
|
clearTimeout(this.reconnectTimer);
|
|
2674
2701
|
}
|
|
2675
|
-
this.
|
|
2702
|
+
this.reconnectAttempts++;
|
|
2703
|
+
const baseDelay = Math.min(3e4, Math.pow(2, this.reconnectAttempts) * 1e3);
|
|
2704
|
+
const jitter = Math.random() * 1e3;
|
|
2705
|
+
const delay = baseDelay + jitter;
|
|
2706
|
+
console.log(`\u{1F504} Scheduling reconnect attempt ${this.reconnectAttempts} in ${Math.round(delay)}ms`);
|
|
2707
|
+
this.reconnectTimer = globalThis.setTimeout(async () => {
|
|
2676
2708
|
if (this.isSubscribed) {
|
|
2677
2709
|
try {
|
|
2678
2710
|
await this.connectWebSocket();
|
|
@@ -2691,7 +2723,7 @@ var BlinkRealtimeChannel = class {
|
|
|
2691
2723
|
this.scheduleReconnect();
|
|
2692
2724
|
}
|
|
2693
2725
|
}
|
|
2694
|
-
},
|
|
2726
|
+
}, delay);
|
|
2695
2727
|
}
|
|
2696
2728
|
cleanup() {
|
|
2697
2729
|
this.isSubscribed = false;
|
|
@@ -2717,6 +2749,7 @@ var BlinkRealtimeImpl = class {
|
|
|
2717
2749
|
this.projectId = projectId;
|
|
2718
2750
|
}
|
|
2719
2751
|
channels = /* @__PURE__ */ new Map();
|
|
2752
|
+
handlers = {};
|
|
2720
2753
|
channel(name) {
|
|
2721
2754
|
if (!this.channels.has(name)) {
|
|
2722
2755
|
this.channels.set(name, new BlinkRealtimeChannel(name, this.httpClient, this.projectId));
|
|
@@ -2726,7 +2759,21 @@ var BlinkRealtimeImpl = class {
|
|
|
2726
2759
|
async subscribe(channelName, callback, options = {}) {
|
|
2727
2760
|
const channel = this.channel(channelName);
|
|
2728
2761
|
await channel.subscribe(options);
|
|
2729
|
-
|
|
2762
|
+
const state = this.handlers[channelName] ??= {
|
|
2763
|
+
msgHandlers: /* @__PURE__ */ new Set(),
|
|
2764
|
+
presHandlers: /* @__PURE__ */ new Set(),
|
|
2765
|
+
subscribed: true
|
|
2766
|
+
};
|
|
2767
|
+
state.msgHandlers.add(callback);
|
|
2768
|
+
const messageUnsub = channel.onMessage(callback);
|
|
2769
|
+
return () => {
|
|
2770
|
+
messageUnsub();
|
|
2771
|
+
state.msgHandlers.delete(callback);
|
|
2772
|
+
if (state.msgHandlers.size === 0 && state.presHandlers.size === 0) {
|
|
2773
|
+
channel.unsubscribe();
|
|
2774
|
+
delete this.handlers[channelName];
|
|
2775
|
+
}
|
|
2776
|
+
};
|
|
2730
2777
|
}
|
|
2731
2778
|
async publish(channelName, type, data, options = {}) {
|
|
2732
2779
|
const channel = this.channel(channelName);
|
|
@@ -2738,7 +2785,21 @@ var BlinkRealtimeImpl = class {
|
|
|
2738
2785
|
}
|
|
2739
2786
|
onPresence(channelName, callback) {
|
|
2740
2787
|
const channel = this.channel(channelName);
|
|
2741
|
-
|
|
2788
|
+
const state = this.handlers[channelName] ??= {
|
|
2789
|
+
msgHandlers: /* @__PURE__ */ new Set(),
|
|
2790
|
+
presHandlers: /* @__PURE__ */ new Set(),
|
|
2791
|
+
subscribed: false
|
|
2792
|
+
};
|
|
2793
|
+
state.presHandlers.add(callback);
|
|
2794
|
+
const presenceUnsub = channel.onPresence(callback);
|
|
2795
|
+
return () => {
|
|
2796
|
+
presenceUnsub();
|
|
2797
|
+
state.presHandlers.delete(callback);
|
|
2798
|
+
if (state.msgHandlers.size === 0 && state.presHandlers.size === 0) {
|
|
2799
|
+
channel.unsubscribe();
|
|
2800
|
+
delete this.handlers[channelName];
|
|
2801
|
+
}
|
|
2802
|
+
};
|
|
2742
2803
|
}
|
|
2743
2804
|
};
|
|
2744
2805
|
|