@rawdash/sdk-runtime 0.28.0 → 0.29.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.
- package/dist/index.d.ts +6 -0
- package/dist/index.js +42 -10
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,9 @@ interface SubscribeOptions {
|
|
|
14
14
|
failingBackoffMs?: number;
|
|
15
15
|
lateRetryStartMs?: number;
|
|
16
16
|
lateRetryMaxMs?: number;
|
|
17
|
+
bootstrapRetryStartMs?: number;
|
|
18
|
+
bootstrapRetryMaxMs?: number;
|
|
19
|
+
bootstrapErrorAfterAttempts?: number;
|
|
17
20
|
defaultIntervalSeconds?: number;
|
|
18
21
|
jitterMs?: number;
|
|
19
22
|
now?: () => number;
|
|
@@ -33,6 +36,9 @@ interface ResolvedOptions {
|
|
|
33
36
|
failingBackoffMs: number;
|
|
34
37
|
lateRetryStartMs: number;
|
|
35
38
|
lateRetryMaxMs: number;
|
|
39
|
+
bootstrapRetryStartMs: number;
|
|
40
|
+
bootstrapRetryMaxMs: number;
|
|
41
|
+
bootstrapErrorAfterAttempts: number;
|
|
36
42
|
defaultIntervalSeconds: number;
|
|
37
43
|
jitterMs: number;
|
|
38
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
|
};
|
|
@@ -24,6 +27,9 @@ function subscribe(source, dashboardId, callbacks, options = {}) {
|
|
|
24
27
|
let visibilityCleanup = null;
|
|
25
28
|
let bootstrapRetryHandle = null;
|
|
26
29
|
let bootstrapSettled = false;
|
|
30
|
+
let bootstrapAttempts = 0;
|
|
31
|
+
let bootstrapRetryDelayMs = 0;
|
|
32
|
+
let bootstrapRetryPending = false;
|
|
27
33
|
function settleBootstrap() {
|
|
28
34
|
if (bootstrapSettled) {
|
|
29
35
|
return;
|
|
@@ -97,6 +103,8 @@ function subscribe(source, dashboardId, callbacks, options = {}) {
|
|
|
97
103
|
if (stopped) {
|
|
98
104
|
return;
|
|
99
105
|
}
|
|
106
|
+
bootstrapAttempts = 0;
|
|
107
|
+
bootstrapRetryDelayMs = 0;
|
|
100
108
|
for (const widget of widgets) {
|
|
101
109
|
applyWidget(widget);
|
|
102
110
|
}
|
|
@@ -105,18 +113,34 @@ function subscribe(source, dashboardId, callbacks, options = {}) {
|
|
|
105
113
|
if (stopped) {
|
|
106
114
|
return;
|
|
107
115
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
116
|
+
bootstrapAttempts += 1;
|
|
117
|
+
if (bootstrapAttempts >= opts.bootstrapErrorAfterAttempts) {
|
|
118
|
+
settleBootstrap();
|
|
119
|
+
callbacks.onError?.(err);
|
|
112
120
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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;
|
|
119
136
|
}
|
|
137
|
+
bootstrapRetryPending = false;
|
|
138
|
+
bootstrapRetryHandle = setTimer(() => {
|
|
139
|
+
bootstrapRetryHandle = null;
|
|
140
|
+
if (!stopped) {
|
|
141
|
+
void bootstrap();
|
|
142
|
+
}
|
|
143
|
+
}, bootstrapRetryDelayMs);
|
|
120
144
|
}
|
|
121
145
|
if (visibility) {
|
|
122
146
|
visibilityCleanup = visibility.onChange(() => {
|
|
@@ -130,10 +154,18 @@ function subscribe(source, dashboardId, callbacks, options = {}) {
|
|
|
130
154
|
t.timer = null;
|
|
131
155
|
}
|
|
132
156
|
}
|
|
157
|
+
if (bootstrapRetryHandle !== null) {
|
|
158
|
+
clearTimer(bootstrapRetryHandle);
|
|
159
|
+
bootstrapRetryHandle = null;
|
|
160
|
+
bootstrapRetryPending = true;
|
|
161
|
+
}
|
|
133
162
|
} else {
|
|
134
163
|
for (const t of trackers.values()) {
|
|
135
164
|
schedule(t, 0);
|
|
136
165
|
}
|
|
166
|
+
if (bootstrapRetryPending) {
|
|
167
|
+
scheduleBootstrapRetry();
|
|
168
|
+
}
|
|
137
169
|
}
|
|
138
170
|
});
|
|
139
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 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 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 let bootstrapSettled = 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 for (const widget of widgets) {\n applyWidget(widget);\n }\n settleBootstrap();\n } catch (err) {\n if (stopped) {\n return;\n }\n settleBootstrap();\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":"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","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.29.0",
|
|
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.29.0",
|
|
26
|
+
"@rawdash/sdk-client": "0.29.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"tsup": "^8.0.0",
|