@rawdash/sdk-runtime 0.27.0 → 0.28.2
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.ts +7 -0
- package/dist/index.js +51 -9
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ interface SubscribeCallbacks {
|
|
|
5
5
|
onWidgetUnchanged?: (widget: CachedWidget) => void;
|
|
6
6
|
onWidgetFailing?: (widget: CachedWidget) => void;
|
|
7
7
|
onError?: (error: unknown) => void;
|
|
8
|
+
onBootstrapped?: () => void;
|
|
8
9
|
}
|
|
9
10
|
interface SubscribeOptions {
|
|
10
11
|
syncingPollMs?: number;
|
|
@@ -13,6 +14,9 @@ interface SubscribeOptions {
|
|
|
13
14
|
failingBackoffMs?: number;
|
|
14
15
|
lateRetryStartMs?: number;
|
|
15
16
|
lateRetryMaxMs?: number;
|
|
17
|
+
bootstrapRetryStartMs?: number;
|
|
18
|
+
bootstrapRetryMaxMs?: number;
|
|
19
|
+
bootstrapErrorAfterAttempts?: number;
|
|
16
20
|
defaultIntervalSeconds?: number;
|
|
17
21
|
jitterMs?: number;
|
|
18
22
|
now?: () => number;
|
|
@@ -32,6 +36,9 @@ interface ResolvedOptions {
|
|
|
32
36
|
failingBackoffMs: number;
|
|
33
37
|
lateRetryStartMs: number;
|
|
34
38
|
lateRetryMaxMs: number;
|
|
39
|
+
bootstrapRetryStartMs: number;
|
|
40
|
+
bootstrapRetryMaxMs: number;
|
|
41
|
+
bootstrapErrorAfterAttempts: number;
|
|
35
42
|
defaultIntervalSeconds: number;
|
|
36
43
|
jitterMs: number;
|
|
37
44
|
}
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,9 @@ var DEFAULT_OPTIONS = {
|
|
|
6
6
|
failingBackoffMs: 6e4,
|
|
7
7
|
lateRetryStartMs: 3e3,
|
|
8
8
|
lateRetryMaxMs: 3e4,
|
|
9
|
+
bootstrapRetryStartMs: 1e3,
|
|
10
|
+
bootstrapRetryMaxMs: 3e4,
|
|
11
|
+
bootstrapErrorAfterAttempts: 3,
|
|
9
12
|
defaultIntervalSeconds: 300,
|
|
10
13
|
jitterMs: 2e3
|
|
11
14
|
};
|
|
@@ -23,6 +26,17 @@ function subscribe(source, dashboardId, callbacks, options = {}) {
|
|
|
23
26
|
let stopped = false;
|
|
24
27
|
let visibilityCleanup = null;
|
|
25
28
|
let bootstrapRetryHandle = null;
|
|
29
|
+
let bootstrapSettled = false;
|
|
30
|
+
let bootstrapAttempts = 0;
|
|
31
|
+
let bootstrapRetryDelayMs = 0;
|
|
32
|
+
let bootstrapRetryPending = false;
|
|
33
|
+
function settleBootstrap() {
|
|
34
|
+
if (bootstrapSettled) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
bootstrapSettled = true;
|
|
38
|
+
callbacks.onBootstrapped?.();
|
|
39
|
+
}
|
|
26
40
|
function schedule(t, delayMs) {
|
|
27
41
|
if (stopped) {
|
|
28
42
|
return;
|
|
@@ -89,24 +103,44 @@ function subscribe(source, dashboardId, callbacks, options = {}) {
|
|
|
89
103
|
if (stopped) {
|
|
90
104
|
return;
|
|
91
105
|
}
|
|
106
|
+
bootstrapAttempts = 0;
|
|
107
|
+
bootstrapRetryDelayMs = 0;
|
|
92
108
|
for (const widget of widgets) {
|
|
93
109
|
applyWidget(widget);
|
|
94
110
|
}
|
|
111
|
+
settleBootstrap();
|
|
95
112
|
} catch (err) {
|
|
96
113
|
if (stopped) {
|
|
97
114
|
return;
|
|
98
115
|
}
|
|
99
|
-
|
|
100
|
-
if (
|
|
101
|
-
|
|
116
|
+
bootstrapAttempts += 1;
|
|
117
|
+
if (bootstrapAttempts >= opts.bootstrapErrorAfterAttempts) {
|
|
118
|
+
settleBootstrap();
|
|
119
|
+
callbacks.onError?.(err);
|
|
102
120
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
121
|
+
bootstrapRetryDelayMs = bootstrapRetryDelayMs <= 0 ? Math.max(1, opts.bootstrapRetryStartMs) : Math.min(bootstrapRetryDelayMs * 2, opts.bootstrapRetryMaxMs);
|
|
122
|
+
scheduleBootstrapRetry();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function scheduleBootstrapRetry() {
|
|
126
|
+
if (stopped) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (bootstrapRetryHandle !== null) {
|
|
130
|
+
clearTimer(bootstrapRetryHandle);
|
|
131
|
+
bootstrapRetryHandle = null;
|
|
132
|
+
}
|
|
133
|
+
if (visibility && visibility.isHidden()) {
|
|
134
|
+
bootstrapRetryPending = true;
|
|
135
|
+
return;
|
|
109
136
|
}
|
|
137
|
+
bootstrapRetryPending = false;
|
|
138
|
+
bootstrapRetryHandle = setTimer(() => {
|
|
139
|
+
bootstrapRetryHandle = null;
|
|
140
|
+
if (!stopped) {
|
|
141
|
+
void bootstrap();
|
|
142
|
+
}
|
|
143
|
+
}, bootstrapRetryDelayMs);
|
|
110
144
|
}
|
|
111
145
|
if (visibility) {
|
|
112
146
|
visibilityCleanup = visibility.onChange(() => {
|
|
@@ -120,10 +154,18 @@ function subscribe(source, dashboardId, callbacks, options = {}) {
|
|
|
120
154
|
t.timer = null;
|
|
121
155
|
}
|
|
122
156
|
}
|
|
157
|
+
if (bootstrapRetryHandle !== null) {
|
|
158
|
+
clearTimer(bootstrapRetryHandle);
|
|
159
|
+
bootstrapRetryHandle = null;
|
|
160
|
+
bootstrapRetryPending = true;
|
|
161
|
+
}
|
|
123
162
|
} else {
|
|
124
163
|
for (const t of trackers.values()) {
|
|
125
164
|
schedule(t, 0);
|
|
126
165
|
}
|
|
166
|
+
if (bootstrapRetryPending) {
|
|
167
|
+
scheduleBootstrapRetry();
|
|
168
|
+
}
|
|
127
169
|
}
|
|
128
170
|
});
|
|
129
171
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/engine.ts"],"sourcesContent":["import type { CachedWidget, DataSource, WidgetSyncState } from '@rawdash/core';\n\nexport interface SubscribeCallbacks {\n onWidgetUpdated: (widget: CachedWidget) => void;\n onWidgetUnchanged?: (widget: CachedWidget) => void;\n onWidgetFailing?: (widget: CachedWidget) => void;\n onError?: (error: unknown) => void;\n}\n\nexport interface SubscribeOptions {\n syncingPollMs?: number;\n syncingPollMaxMs?: number;\n unsyncedPollMs?: number;\n failingBackoffMs?: number;\n lateRetryStartMs?: number;\n lateRetryMaxMs?: number;\n defaultIntervalSeconds?: number;\n jitterMs?: number;\n now?: () => number;\n setTimeout?: (cb: () => void, ms: number) => unknown;\n clearTimeout?: (handle: unknown) => void;\n random?: () => number;\n visibility?: VisibilitySource | null;\n}\n\nexport interface VisibilitySource {\n isHidden(): boolean;\n onChange(listener: () => void): () => void;\n}\n\ninterface ResolvedOptions {\n syncingPollMs: number;\n syncingPollMaxMs: number;\n unsyncedPollMs: number;\n failingBackoffMs: number;\n lateRetryStartMs: number;\n lateRetryMaxMs: number;\n defaultIntervalSeconds: number;\n jitterMs: number;\n}\n\nconst DEFAULT_OPTIONS: ResolvedOptions = {\n syncingPollMs: 3_000,\n syncingPollMaxMs: 60_000,\n unsyncedPollMs: 10_000,\n failingBackoffMs: 60_000,\n lateRetryStartMs: 3_000,\n lateRetryMaxMs: 30_000,\n defaultIntervalSeconds: 300,\n jitterMs: 2_000,\n};\n\ntype Timer = unknown;\n\ninterface WidgetTracker {\n widgetId: string;\n lastSyncAtMs: number | null;\n lastSyncState: WidgetSyncState | undefined;\n failingNotified: boolean;\n lateRetryDelayMs: number | null;\n syncingSinceMs: number | null;\n timer: Timer | null;\n}\n\nexport type Unsubscribe = () => void;\n\nexport function subscribe(\n source: DataSource,\n dashboardId: string,\n callbacks: SubscribeCallbacks,\n options: SubscribeOptions = {},\n): Unsubscribe {\n const opts = {\n ...DEFAULT_OPTIONS,\n ...options,\n };\n const now = opts.now ?? (() => Date.now());\n const setTimer = opts.setTimeout ?? ((cb, ms) => setTimeout(cb, ms));\n const clearTimer = opts.clearTimeout ?? ((h) => clearTimeout(h as never));\n const random = opts.random ?? Math.random;\n const visibility = opts.visibility ?? defaultVisibility();\n\n const trackers = new Map<string, WidgetTracker>();\n let stopped = false;\n let visibilityCleanup: (() => void) | null = null;\n let bootstrapRetryHandle: Timer | null = null;\n\n function schedule(t: WidgetTracker, delayMs: number): void {\n if (stopped) {\n return;\n }\n if (t.timer !== null) {\n clearTimer(t.timer);\n t.timer = null;\n }\n if (visibility && visibility.isHidden()) {\n return;\n }\n const jitter = Math.floor(random() * opts.jitterMs);\n t.timer = setTimer(\n () => {\n t.timer = null;\n void poll(t);\n },\n Math.max(0, delayMs + jitter),\n );\n }\n\n function tracker(widgetId: string): WidgetTracker {\n let t = trackers.get(widgetId);\n if (!t) {\n t = {\n widgetId,\n lastSyncAtMs: null,\n lastSyncState: undefined,\n failingNotified: false,\n lateRetryDelayMs: null,\n syncingSinceMs: null,\n timer: null,\n };\n trackers.set(widgetId, t);\n }\n return t;\n }\n\n function applyWidget(widget: CachedWidget): void {\n const t = tracker(widget.widgetId);\n const nextDelay = handleWidget(t, widget, now(), opts, callbacks);\n schedule(t, nextDelay);\n }\n\n async function poll(t: WidgetTracker): Promise<void> {\n if (stopped) {\n return;\n }\n try {\n const widget = await source.getWidget(dashboardId, t.widgetId);\n if (stopped) {\n return;\n }\n const nextDelay = handleWidget(t, widget, now(), opts, callbacks);\n schedule(t, nextDelay);\n } catch (err) {\n if (stopped) {\n return;\n }\n callbacks.onError?.(err);\n schedule(t, opts.failingBackoffMs);\n }\n }\n\n async function bootstrap(): Promise<void> {\n try {\n const widgets = await source.getWidgets(dashboardId);\n if (stopped) {\n return;\n }\n for (const widget of widgets) {\n applyWidget(widget);\n }\n } catch (err) {\n if (stopped) {\n return;\n }\n callbacks.onError?.(err);\n if (bootstrapRetryHandle !== null) {\n clearTimer(bootstrapRetryHandle);\n }\n bootstrapRetryHandle = setTimer(() => {\n bootstrapRetryHandle = null;\n if (!stopped) {\n void bootstrap();\n }\n }, opts.failingBackoffMs);\n }\n }\n\n if (visibility) {\n visibilityCleanup = visibility.onChange(() => {\n if (stopped) {\n return;\n }\n if (visibility.isHidden()) {\n for (const t of trackers.values()) {\n if (t.timer !== null) {\n clearTimer(t.timer);\n t.timer = null;\n }\n }\n } else {\n for (const t of trackers.values()) {\n schedule(t, 0);\n }\n }\n });\n }\n\n void bootstrap();\n\n return () => {\n stopped = true;\n for (const t of trackers.values()) {\n if (t.timer !== null) {\n clearTimer(t.timer);\n t.timer = null;\n }\n }\n if (bootstrapRetryHandle !== null) {\n clearTimer(bootstrapRetryHandle);\n bootstrapRetryHandle = null;\n }\n if (visibilityCleanup) {\n visibilityCleanup();\n }\n };\n}\n\nexport function handleWidget(\n t: WidgetTracker,\n widget: CachedWidget,\n nowMs: number,\n opts: ResolvedOptions,\n callbacks: SubscribeCallbacks,\n): number {\n const incomingSyncAtMs = widget.cachedAt\n ? new Date(widget.cachedAt).getTime()\n : null;\n const rawIntervalSeconds =\n widget.syncIntervalSeconds ?? opts.defaultIntervalSeconds;\n const safeIntervalSeconds =\n Number.isFinite(rawIntervalSeconds) && rawIntervalSeconds > 0\n ? rawIntervalSeconds\n : opts.defaultIntervalSeconds;\n const intervalMs = safeIntervalSeconds * 1000;\n const state = widget.syncState;\n\n const previousSyncAtMs = t.lastSyncAtMs;\n const advanced =\n incomingSyncAtMs !== null && incomingSyncAtMs !== previousSyncAtMs;\n\n switch (state) {\n case 'fresh': {\n if (advanced || previousSyncAtMs === null) {\n t.lastSyncAtMs = incomingSyncAtMs;\n t.lastSyncState = state;\n t.failingNotified = false;\n t.lateRetryDelayMs = null;\n t.syncingSinceMs = null;\n callbacks.onWidgetUpdated(widget);\n if (incomingSyncAtMs === null) {\n return intervalMs;\n }\n const expected = incomingSyncAtMs + intervalMs;\n return Math.max(0, expected - nowMs);\n }\n callbacks.onWidgetUnchanged?.(widget);\n const expected = (incomingSyncAtMs ?? nowMs) + intervalMs;\n const baseDelay = Math.max(0, expected - nowMs);\n const giveUpAtMs = (incomingSyncAtMs ?? nowMs) + 2 * intervalMs;\n if (nowMs >= giveUpAtMs) {\n t.lateRetryDelayMs = null;\n return Math.max(baseDelay, intervalMs);\n }\n const prev = t.lateRetryDelayMs ?? 0;\n const next =\n prev === 0\n ? opts.lateRetryStartMs\n : Math.min(prev * 2, opts.lateRetryMaxMs);\n t.lateRetryDelayMs = next;\n t.lastSyncState = state;\n return next;\n }\n case 'syncing': {\n t.lastSyncState = state;\n if (t.syncingSinceMs === null) {\n t.syncingSinceMs = nowMs;\n }\n callbacks.onWidgetUnchanged?.(widget);\n const elapsed = nowMs - t.syncingSinceMs;\n if (elapsed >= opts.syncingPollMaxMs) {\n return intervalMs;\n }\n return opts.syncingPollMs;\n }\n case 'failing':\n case 'stale': {\n t.lastSyncState = state;\n if (!t.failingNotified) {\n t.failingNotified = true;\n callbacks.onWidgetFailing?.(widget);\n } else {\n callbacks.onWidgetUnchanged?.(widget);\n }\n return opts.failingBackoffMs;\n }\n case 'unsynced': {\n t.lastSyncState = state;\n callbacks.onWidgetUnchanged?.(widget);\n return opts.unsyncedPollMs;\n }\n default: {\n if (advanced || previousSyncAtMs === null) {\n t.lastSyncAtMs = incomingSyncAtMs;\n callbacks.onWidgetUpdated(widget);\n } else {\n callbacks.onWidgetUnchanged?.(widget);\n }\n t.lastSyncState = state;\n return intervalMs;\n }\n }\n}\n\nfunction defaultVisibility(): VisibilitySource | null {\n if (typeof document === 'undefined') {\n return null;\n }\n const doc = document;\n return {\n isHidden: () => doc.hidden === true,\n onChange: (listener) => {\n const handler = () => listener();\n doc.addEventListener('visibilitychange', handler);\n if (typeof window !== 'undefined') {\n window.addEventListener('focus', handler);\n }\n return () => {\n doc.removeEventListener('visibilitychange', handler);\n if (typeof window !== 'undefined') {\n window.removeEventListener('focus', handler);\n }\n };\n },\n };\n}\n"],"mappings":";AAyCA,IAAM,kBAAmC;AAAA,EACvC,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,wBAAwB;AAAA,EACxB,UAAU;AACZ;AAgBO,SAAS,UACd,QACA,aACA,WACA,UAA4B,CAAC,GAChB;AACb,QAAM,OAAO;AAAA,IACX,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AACA,QAAM,MAAM,KAAK,QAAQ,MAAM,KAAK,IAAI;AACxC,QAAM,WAAW,KAAK,eAAe,CAAC,IAAI,OAAO,WAAW,IAAI,EAAE;AAClE,QAAM,aAAa,KAAK,iBAAiB,CAAC,MAAM,aAAa,CAAU;AACvE,QAAM,SAAS,KAAK,UAAU,KAAK;AACnC,QAAM,aAAa,KAAK,cAAc,kBAAkB;AAExD,QAAM,WAAW,oBAAI,IAA2B;AAChD,MAAI,UAAU;AACd,MAAI,oBAAyC;AAC7C,MAAI,uBAAqC;AAEzC,WAAS,SAAS,GAAkB,SAAuB;AACzD,QAAI,SAAS;AACX;AAAA,IACF;AACA,QAAI,EAAE,UAAU,MAAM;AACpB,iBAAW,EAAE,KAAK;AAClB,QAAE,QAAQ;AAAA,IACZ;AACA,QAAI,cAAc,WAAW,SAAS,GAAG;AACvC;AAAA,IACF;AACA,UAAM,SAAS,KAAK,MAAM,OAAO,IAAI,KAAK,QAAQ;AAClD,MAAE,QAAQ;AAAA,MACR,MAAM;AACJ,UAAE,QAAQ;AACV,aAAK,KAAK,CAAC;AAAA,MACb;AAAA,MACA,KAAK,IAAI,GAAG,UAAU,MAAM;AAAA,IAC9B;AAAA,EACF;AAEA,WAAS,QAAQ,UAAiC;AAChD,QAAI,IAAI,SAAS,IAAI,QAAQ;AAC7B,QAAI,CAAC,GAAG;AACN,UAAI;AAAA,QACF;AAAA,QACA,cAAc;AAAA,QACd,eAAe;AAAA,QACf,iBAAiB;AAAA,QACjB,kBAAkB;AAAA,QAClB,gBAAgB;AAAA,QAChB,OAAO;AAAA,MACT;AACA,eAAS,IAAI,UAAU,CAAC;AAAA,IAC1B;AACA,WAAO;AAAA,EACT;AAEA,WAAS,YAAY,QAA4B;AAC/C,UAAM,IAAI,QAAQ,OAAO,QAAQ;AACjC,UAAM,YAAY,aAAa,GAAG,QAAQ,IAAI,GAAG,MAAM,SAAS;AAChE,aAAS,GAAG,SAAS;AAAA,EACvB;AAEA,iBAAe,KAAK,GAAiC;AACnD,QAAI,SAAS;AACX;AAAA,IACF;AACA,QAAI;AACF,YAAM,SAAS,MAAM,OAAO,UAAU,aAAa,EAAE,QAAQ;AAC7D,UAAI,SAAS;AACX;AAAA,MACF;AACA,YAAM,YAAY,aAAa,GAAG,QAAQ,IAAI,GAAG,MAAM,SAAS;AAChE,eAAS,GAAG,SAAS;AAAA,IACvB,SAAS,KAAK;AACZ,UAAI,SAAS;AACX;AAAA,MACF;AACA,gBAAU,UAAU,GAAG;AACvB,eAAS,GAAG,KAAK,gBAAgB;AAAA,IACnC;AAAA,EACF;AAEA,iBAAe,YAA2B;AACxC,QAAI;AACF,YAAM,UAAU,MAAM,OAAO,WAAW,WAAW;AACnD,UAAI,SAAS;AACX;AAAA,MACF;AACA,iBAAW,UAAU,SAAS;AAC5B,oBAAY,MAAM;AAAA,MACpB;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,SAAS;AACX;AAAA,MACF;AACA,gBAAU,UAAU,GAAG;AACvB,UAAI,yBAAyB,MAAM;AACjC,mBAAW,oBAAoB;AAAA,MACjC;AACA,6BAAuB,SAAS,MAAM;AACpC,+BAAuB;AACvB,YAAI,CAAC,SAAS;AACZ,eAAK,UAAU;AAAA,QACjB;AAAA,MACF,GAAG,KAAK,gBAAgB;AAAA,IAC1B;AAAA,EACF;AAEA,MAAI,YAAY;AACd,wBAAoB,WAAW,SAAS,MAAM;AAC5C,UAAI,SAAS;AACX;AAAA,MACF;AACA,UAAI,WAAW,SAAS,GAAG;AACzB,mBAAW,KAAK,SAAS,OAAO,GAAG;AACjC,cAAI,EAAE,UAAU,MAAM;AACpB,uBAAW,EAAE,KAAK;AAClB,cAAE,QAAQ;AAAA,UACZ;AAAA,QACF;AAAA,MACF,OAAO;AACL,mBAAW,KAAK,SAAS,OAAO,GAAG;AACjC,mBAAS,GAAG,CAAC;AAAA,QACf;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,OAAK,UAAU;AAEf,SAAO,MAAM;AACX,cAAU;AACV,eAAW,KAAK,SAAS,OAAO,GAAG;AACjC,UAAI,EAAE,UAAU,MAAM;AACpB,mBAAW,EAAE,KAAK;AAClB,UAAE,QAAQ;AAAA,MACZ;AAAA,IACF;AACA,QAAI,yBAAyB,MAAM;AACjC,iBAAW,oBAAoB;AAC/B,6BAAuB;AAAA,IACzB;AACA,QAAI,mBAAmB;AACrB,wBAAkB;AAAA,IACpB;AAAA,EACF;AACF;AAEO,SAAS,aACd,GACA,QACA,OACA,MACA,WACQ;AACR,QAAM,mBAAmB,OAAO,WAC5B,IAAI,KAAK,OAAO,QAAQ,EAAE,QAAQ,IAClC;AACJ,QAAM,qBACJ,OAAO,uBAAuB,KAAK;AACrC,QAAM,sBACJ,OAAO,SAAS,kBAAkB,KAAK,qBAAqB,IACxD,qBACA,KAAK;AACX,QAAM,aAAa,sBAAsB;AACzC,QAAM,QAAQ,OAAO;AAErB,QAAM,mBAAmB,EAAE;AAC3B,QAAM,WACJ,qBAAqB,QAAQ,qBAAqB;AAEpD,UAAQ,OAAO;AAAA,IACb,KAAK,SAAS;AACZ,UAAI,YAAY,qBAAqB,MAAM;AACzC,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAClB,UAAE,kBAAkB;AACpB,UAAE,mBAAmB;AACrB,UAAE,iBAAiB;AACnB,kBAAU,gBAAgB,MAAM;AAChC,YAAI,qBAAqB,MAAM;AAC7B,iBAAO;AAAA,QACT;AACA,cAAMA,YAAW,mBAAmB;AACpC,eAAO,KAAK,IAAI,GAAGA,YAAW,KAAK;AAAA,MACrC;AACA,gBAAU,oBAAoB,MAAM;AACpC,YAAM,YAAY,oBAAoB,SAAS;AAC/C,YAAM,YAAY,KAAK,IAAI,GAAG,WAAW,KAAK;AAC9C,YAAM,cAAc,oBAAoB,SAAS,IAAI;AACrD,UAAI,SAAS,YAAY;AACvB,UAAE,mBAAmB;AACrB,eAAO,KAAK,IAAI,WAAW,UAAU;AAAA,MACvC;AACA,YAAM,OAAO,EAAE,oBAAoB;AACnC,YAAM,OACJ,SAAS,IACL,KAAK,mBACL,KAAK,IAAI,OAAO,GAAG,KAAK,cAAc;AAC5C,QAAE,mBAAmB;AACrB,QAAE,gBAAgB;AAClB,aAAO;AAAA,IACT;AAAA,IACA,KAAK,WAAW;AACd,QAAE,gBAAgB;AAClB,UAAI,EAAE,mBAAmB,MAAM;AAC7B,UAAE,iBAAiB;AAAA,MACrB;AACA,gBAAU,oBAAoB,MAAM;AACpC,YAAM,UAAU,QAAQ,EAAE;AAC1B,UAAI,WAAW,KAAK,kBAAkB;AACpC,eAAO;AAAA,MACT;AACA,aAAO,KAAK;AAAA,IACd;AAAA,IACA,KAAK;AAAA,IACL,KAAK,SAAS;AACZ,QAAE,gBAAgB;AAClB,UAAI,CAAC,EAAE,iBAAiB;AACtB,UAAE,kBAAkB;AACpB,kBAAU,kBAAkB,MAAM;AAAA,MACpC,OAAO;AACL,kBAAU,oBAAoB,MAAM;AAAA,MACtC;AACA,aAAO,KAAK;AAAA,IACd;AAAA,IACA,KAAK,YAAY;AACf,QAAE,gBAAgB;AAClB,gBAAU,oBAAoB,MAAM;AACpC,aAAO,KAAK;AAAA,IACd;AAAA,IACA,SAAS;AACP,UAAI,YAAY,qBAAqB,MAAM;AACzC,UAAE,eAAe;AACjB,kBAAU,gBAAgB,MAAM;AAAA,MAClC,OAAO;AACL,kBAAU,oBAAoB,MAAM;AAAA,MACtC;AACA,QAAE,gBAAgB;AAClB,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,oBAA6C;AACpD,MAAI,OAAO,aAAa,aAAa;AACnC,WAAO;AAAA,EACT;AACA,QAAM,MAAM;AACZ,SAAO;AAAA,IACL,UAAU,MAAM,IAAI,WAAW;AAAA,IAC/B,UAAU,CAAC,aAAa;AACtB,YAAM,UAAU,MAAM,SAAS;AAC/B,UAAI,iBAAiB,oBAAoB,OAAO;AAChD,UAAI,OAAO,WAAW,aAAa;AACjC,eAAO,iBAAiB,SAAS,OAAO;AAAA,MAC1C;AACA,aAAO,MAAM;AACX,YAAI,oBAAoB,oBAAoB,OAAO;AACnD,YAAI,OAAO,WAAW,aAAa;AACjC,iBAAO,oBAAoB,SAAS,OAAO;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":["expected"]}
|
|
1
|
+
{"version":3,"sources":["../src/engine.ts"],"sourcesContent":["import type { CachedWidget, DataSource, WidgetSyncState } from '@rawdash/core';\n\nexport interface SubscribeCallbacks {\n onWidgetUpdated: (widget: CachedWidget) => void;\n onWidgetUnchanged?: (widget: CachedWidget) => void;\n onWidgetFailing?: (widget: CachedWidget) => void;\n onError?: (error: unknown) => void;\n onBootstrapped?: () => void;\n}\n\nexport interface SubscribeOptions {\n syncingPollMs?: number;\n syncingPollMaxMs?: number;\n unsyncedPollMs?: number;\n failingBackoffMs?: number;\n lateRetryStartMs?: number;\n lateRetryMaxMs?: number;\n bootstrapRetryStartMs?: number;\n bootstrapRetryMaxMs?: number;\n bootstrapErrorAfterAttempts?: number;\n defaultIntervalSeconds?: number;\n jitterMs?: number;\n now?: () => number;\n setTimeout?: (cb: () => void, ms: number) => unknown;\n clearTimeout?: (handle: unknown) => void;\n random?: () => number;\n visibility?: VisibilitySource | null;\n}\n\nexport interface VisibilitySource {\n isHidden(): boolean;\n onChange(listener: () => void): () => void;\n}\n\ninterface ResolvedOptions {\n syncingPollMs: number;\n syncingPollMaxMs: number;\n unsyncedPollMs: number;\n failingBackoffMs: number;\n lateRetryStartMs: number;\n lateRetryMaxMs: number;\n bootstrapRetryStartMs: number;\n bootstrapRetryMaxMs: number;\n bootstrapErrorAfterAttempts: number;\n defaultIntervalSeconds: number;\n jitterMs: number;\n}\n\nconst DEFAULT_OPTIONS: ResolvedOptions = {\n syncingPollMs: 3_000,\n syncingPollMaxMs: 60_000,\n unsyncedPollMs: 10_000,\n failingBackoffMs: 60_000,\n lateRetryStartMs: 3_000,\n lateRetryMaxMs: 30_000,\n bootstrapRetryStartMs: 1_000,\n bootstrapRetryMaxMs: 30_000,\n bootstrapErrorAfterAttempts: 3,\n defaultIntervalSeconds: 300,\n jitterMs: 2_000,\n};\n\ntype Timer = unknown;\n\ninterface WidgetTracker {\n widgetId: string;\n lastSyncAtMs: number | null;\n lastSyncState: WidgetSyncState | undefined;\n failingNotified: boolean;\n lateRetryDelayMs: number | null;\n syncingSinceMs: number | null;\n timer: Timer | null;\n}\n\nexport type Unsubscribe = () => void;\n\nexport function subscribe(\n source: DataSource,\n dashboardId: string,\n callbacks: SubscribeCallbacks,\n options: SubscribeOptions = {},\n): Unsubscribe {\n const opts = {\n ...DEFAULT_OPTIONS,\n ...options,\n };\n const now = opts.now ?? (() => Date.now());\n const setTimer = opts.setTimeout ?? ((cb, ms) => setTimeout(cb, ms));\n const clearTimer = opts.clearTimeout ?? ((h) => clearTimeout(h as never));\n const random = opts.random ?? Math.random;\n const visibility = opts.visibility ?? defaultVisibility();\n\n const trackers = new Map<string, WidgetTracker>();\n let stopped = false;\n let visibilityCleanup: (() => void) | null = null;\n let bootstrapRetryHandle: Timer | null = null;\n let bootstrapSettled = false;\n let bootstrapAttempts = 0;\n let bootstrapRetryDelayMs = 0;\n let bootstrapRetryPending = false;\n\n function settleBootstrap(): void {\n if (bootstrapSettled) {\n return;\n }\n bootstrapSettled = true;\n callbacks.onBootstrapped?.();\n }\n\n function schedule(t: WidgetTracker, delayMs: number): void {\n if (stopped) {\n return;\n }\n if (t.timer !== null) {\n clearTimer(t.timer);\n t.timer = null;\n }\n if (visibility && visibility.isHidden()) {\n return;\n }\n const jitter = Math.floor(random() * opts.jitterMs);\n t.timer = setTimer(\n () => {\n t.timer = null;\n void poll(t);\n },\n Math.max(0, delayMs + jitter),\n );\n }\n\n function tracker(widgetId: string): WidgetTracker {\n let t = trackers.get(widgetId);\n if (!t) {\n t = {\n widgetId,\n lastSyncAtMs: null,\n lastSyncState: undefined,\n failingNotified: false,\n lateRetryDelayMs: null,\n syncingSinceMs: null,\n timer: null,\n };\n trackers.set(widgetId, t);\n }\n return t;\n }\n\n function applyWidget(widget: CachedWidget): void {\n const t = tracker(widget.widgetId);\n const nextDelay = handleWidget(t, widget, now(), opts, callbacks);\n schedule(t, nextDelay);\n }\n\n async function poll(t: WidgetTracker): Promise<void> {\n if (stopped) {\n return;\n }\n try {\n const widget = await source.getWidget(dashboardId, t.widgetId);\n if (stopped) {\n return;\n }\n const nextDelay = handleWidget(t, widget, now(), opts, callbacks);\n schedule(t, nextDelay);\n } catch (err) {\n if (stopped) {\n return;\n }\n callbacks.onError?.(err);\n schedule(t, opts.failingBackoffMs);\n }\n }\n\n async function bootstrap(): Promise<void> {\n try {\n const widgets = await source.getWidgets(dashboardId);\n if (stopped) {\n return;\n }\n bootstrapAttempts = 0;\n bootstrapRetryDelayMs = 0;\n for (const widget of widgets) {\n applyWidget(widget);\n }\n settleBootstrap();\n } catch (err) {\n if (stopped) {\n return;\n }\n bootstrapAttempts += 1;\n if (bootstrapAttempts >= opts.bootstrapErrorAfterAttempts) {\n settleBootstrap();\n callbacks.onError?.(err);\n }\n bootstrapRetryDelayMs =\n bootstrapRetryDelayMs <= 0\n ? Math.max(1, opts.bootstrapRetryStartMs)\n : Math.min(bootstrapRetryDelayMs * 2, opts.bootstrapRetryMaxMs);\n scheduleBootstrapRetry();\n }\n }\n\n function scheduleBootstrapRetry(): void {\n if (stopped) {\n return;\n }\n if (bootstrapRetryHandle !== null) {\n clearTimer(bootstrapRetryHandle);\n bootstrapRetryHandle = null;\n }\n if (visibility && visibility.isHidden()) {\n bootstrapRetryPending = true;\n return;\n }\n bootstrapRetryPending = false;\n bootstrapRetryHandle = setTimer(() => {\n bootstrapRetryHandle = null;\n if (!stopped) {\n void bootstrap();\n }\n }, bootstrapRetryDelayMs);\n }\n\n if (visibility) {\n visibilityCleanup = visibility.onChange(() => {\n if (stopped) {\n return;\n }\n if (visibility.isHidden()) {\n for (const t of trackers.values()) {\n if (t.timer !== null) {\n clearTimer(t.timer);\n t.timer = null;\n }\n }\n if (bootstrapRetryHandle !== null) {\n clearTimer(bootstrapRetryHandle);\n bootstrapRetryHandle = null;\n bootstrapRetryPending = true;\n }\n } else {\n for (const t of trackers.values()) {\n schedule(t, 0);\n }\n if (bootstrapRetryPending) {\n scheduleBootstrapRetry();\n }\n }\n });\n }\n\n void bootstrap();\n\n return () => {\n stopped = true;\n for (const t of trackers.values()) {\n if (t.timer !== null) {\n clearTimer(t.timer);\n t.timer = null;\n }\n }\n if (bootstrapRetryHandle !== null) {\n clearTimer(bootstrapRetryHandle);\n bootstrapRetryHandle = null;\n }\n if (visibilityCleanup) {\n visibilityCleanup();\n }\n };\n}\n\nexport function handleWidget(\n t: WidgetTracker,\n widget: CachedWidget,\n nowMs: number,\n opts: ResolvedOptions,\n callbacks: SubscribeCallbacks,\n): number {\n const incomingSyncAtMs = widget.cachedAt\n ? new Date(widget.cachedAt).getTime()\n : null;\n const rawIntervalSeconds =\n widget.syncIntervalSeconds ?? opts.defaultIntervalSeconds;\n const safeIntervalSeconds =\n Number.isFinite(rawIntervalSeconds) && rawIntervalSeconds > 0\n ? rawIntervalSeconds\n : opts.defaultIntervalSeconds;\n const intervalMs = safeIntervalSeconds * 1000;\n const state = widget.syncState;\n\n const previousSyncAtMs = t.lastSyncAtMs;\n const advanced =\n incomingSyncAtMs !== null && incomingSyncAtMs !== previousSyncAtMs;\n\n switch (state) {\n case 'fresh': {\n if (advanced || previousSyncAtMs === null) {\n t.lastSyncAtMs = incomingSyncAtMs;\n t.lastSyncState = state;\n t.failingNotified = false;\n t.lateRetryDelayMs = null;\n t.syncingSinceMs = null;\n callbacks.onWidgetUpdated(widget);\n if (incomingSyncAtMs === null) {\n return intervalMs;\n }\n const expected = incomingSyncAtMs + intervalMs;\n return Math.max(0, expected - nowMs);\n }\n callbacks.onWidgetUnchanged?.(widget);\n const expected = (incomingSyncAtMs ?? nowMs) + intervalMs;\n const baseDelay = Math.max(0, expected - nowMs);\n const giveUpAtMs = (incomingSyncAtMs ?? nowMs) + 2 * intervalMs;\n if (nowMs >= giveUpAtMs) {\n t.lateRetryDelayMs = null;\n return Math.max(baseDelay, intervalMs);\n }\n const prev = t.lateRetryDelayMs ?? 0;\n const next =\n prev === 0\n ? opts.lateRetryStartMs\n : Math.min(prev * 2, opts.lateRetryMaxMs);\n t.lateRetryDelayMs = next;\n t.lastSyncState = state;\n return next;\n }\n case 'syncing': {\n t.lastSyncState = state;\n if (t.syncingSinceMs === null) {\n t.syncingSinceMs = nowMs;\n }\n callbacks.onWidgetUnchanged?.(widget);\n const elapsed = nowMs - t.syncingSinceMs;\n if (elapsed >= opts.syncingPollMaxMs) {\n return intervalMs;\n }\n return opts.syncingPollMs;\n }\n case 'failing':\n case 'stale': {\n t.lastSyncState = state;\n if (!t.failingNotified) {\n t.failingNotified = true;\n callbacks.onWidgetFailing?.(widget);\n } else {\n callbacks.onWidgetUnchanged?.(widget);\n }\n return opts.failingBackoffMs;\n }\n case 'unsynced': {\n t.lastSyncState = state;\n callbacks.onWidgetUnchanged?.(widget);\n return opts.unsyncedPollMs;\n }\n default: {\n if (advanced || previousSyncAtMs === null) {\n t.lastSyncAtMs = incomingSyncAtMs;\n callbacks.onWidgetUpdated(widget);\n } else {\n callbacks.onWidgetUnchanged?.(widget);\n }\n t.lastSyncState = state;\n return intervalMs;\n }\n }\n}\n\nfunction defaultVisibility(): VisibilitySource | null {\n if (typeof document === 'undefined') {\n return null;\n }\n const doc = document;\n return {\n isHidden: () => doc.hidden === true,\n onChange: (listener) => {\n const handler = () => listener();\n doc.addEventListener('visibilitychange', handler);\n if (typeof window !== 'undefined') {\n window.addEventListener('focus', handler);\n }\n return () => {\n doc.removeEventListener('visibilitychange', handler);\n if (typeof window !== 'undefined') {\n window.removeEventListener('focus', handler);\n }\n };\n },\n };\n}\n"],"mappings":"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","names":["expected"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rawdash/sdk-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.2",
|
|
4
4
|
"description": "Rawdash auto-polling subscription engine for client-side dashboards",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@rawdash/core": "0.
|
|
26
|
-
"@rawdash/sdk-client": "0.
|
|
25
|
+
"@rawdash/core": "0.28.2",
|
|
26
|
+
"@rawdash/sdk-client": "0.28.2"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"tsup": "^8.0.0",
|