@rawdash/sdk-nextjs 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/README.md CHANGED
@@ -71,6 +71,8 @@ export async function syncDashboard() {
71
71
 
72
72
  For dashboards that stay open all day, `@rawdash/sdk-nextjs/client` exposes `'use client'` hooks backed by the `@rawdash/sdk-runtime` subscription engine. The engine polls on the cadence the server publishes (`cachedAt + syncIntervalSeconds`), polls fast while a sync is in flight, backs off when syncs fail, pauses when the tab is hidden, and refetches on focus.
73
73
 
74
+ `useDashboard` and `useWidget` return a `loading` flag that is `true` until the first fetch settles. Gate your initial render on it so an empty-state placeholder only shows once data has genuinely come back empty, rather than flashing while the first fetch is still in flight.
75
+
74
76
  ```tsx
75
77
  'use client';
76
78
 
@@ -80,8 +82,9 @@ import { useDashboard, useWidget } from '@rawdash/sdk-nextjs/client';
80
82
  const source = http({ baseUrl: '/rawdash' });
81
83
 
82
84
  export function LiveDashboard() {
83
- const { widgets, error } = useDashboard(source, 'engineering');
85
+ const { widgets, error, loading } = useDashboard(source, 'engineering');
84
86
  if (error) return <div>Connection error</div>;
87
+ if (loading) return <div>Loading…</div>;
85
88
  return (
86
89
  <div>
87
90
  {Object.values(widgets).map((w) => (
package/dist/client.d.ts CHANGED
@@ -7,6 +7,7 @@ interface UseDashboardResult {
7
7
  widgets: Record<string, CachedWidget>;
8
8
  syncState: Record<string, WidgetSyncState | undefined>;
9
9
  error: unknown;
10
+ loading: boolean;
10
11
  }
11
12
  interface UseDashboardOptions extends SubscribeOptions {
12
13
  initialWidgets?: CachedWidget[];
@@ -16,6 +17,7 @@ interface UseWidgetResult<TData = unknown> {
16
17
  widget: CachedWidget<TData> | null;
17
18
  syncState: WidgetSyncState | undefined;
18
19
  error: unknown;
20
+ loading: boolean;
19
21
  }
20
22
  declare function useWidget<TData = unknown>(source: DataSource, dashboardId: string, widgetId: string, options?: UseDashboardOptions): UseWidgetResult<TData>;
21
23
 
package/dist/client.js CHANGED
@@ -9,6 +9,9 @@ function useDashboard(source, dashboardId, options = {}) {
9
9
  () => indexWidgets(initialWidgets ?? [])
10
10
  );
11
11
  const [error, setError] = useState(null);
12
+ const [loading, setLoading] = useState(
13
+ () => (initialWidgets?.length ?? 0) === 0
14
+ );
12
15
  const optsRef = useRef(subscribeOptions);
13
16
  optsRef.current = subscribeOptions;
14
17
  const initialWidgetsRef = useRef(initialWidgets);
@@ -16,6 +19,7 @@ function useDashboard(source, dashboardId, options = {}) {
16
19
  useEffect(() => {
17
20
  setWidgets(indexWidgets(initialWidgetsRef.current ?? []));
18
21
  setError(null);
22
+ setLoading((initialWidgetsRef.current?.length ?? 0) === 0);
19
23
  const unsub = subscribe(
20
24
  source,
21
25
  dashboardId,
@@ -34,7 +38,8 @@ function useDashboard(source, dashboardId, options = {}) {
34
38
  setWidgets((prev) => ({ ...prev, [w.widgetId]: w }));
35
39
  setError(null);
36
40
  },
37
- onError: (e) => setError(e)
41
+ onError: (e) => setError(e),
42
+ onBootstrapped: () => setLoading(false)
38
43
  },
39
44
  optsRef.current
40
45
  );
@@ -44,12 +49,16 @@ function useDashboard(source, dashboardId, options = {}) {
44
49
  for (const id of Object.keys(widgets)) {
45
50
  syncState[id] = widgets[id]?.syncState;
46
51
  }
47
- return { widgets, syncState, error };
52
+ return { widgets, syncState, error, loading };
48
53
  }
49
54
  function useWidget(source, dashboardId, widgetId, options = {}) {
50
- const { widgets, error } = useDashboard(source, dashboardId, options);
55
+ const { widgets, error, loading } = useDashboard(
56
+ source,
57
+ dashboardId,
58
+ options
59
+ );
51
60
  const widget = widgets[widgetId] ?? null;
52
- return { widget, syncState: widget?.syncState, error };
61
+ return { widget, syncState: widget?.syncState, error, loading };
53
62
  }
54
63
  function indexWidgets(list) {
55
64
  const out = {};
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts"],"sourcesContent":["'use client';\n\nimport type { CachedWidget, DataSource, WidgetSyncState } from '@rawdash/core';\nimport { subscribe } from '@rawdash/sdk-runtime';\nimport type { SubscribeOptions } from '@rawdash/sdk-runtime';\nimport { useEffect, useRef, useState } from 'react';\n\nexport type {\n SubscribeCallbacks,\n SubscribeOptions,\n Unsubscribe,\n VisibilitySource,\n} from '@rawdash/sdk-runtime';\n\nexport type { CachedWidget, DataSource, WidgetSyncState } from '@rawdash/core';\n\nexport interface UseDashboardResult {\n widgets: Record<string, CachedWidget>;\n syncState: Record<string, WidgetSyncState | undefined>;\n error: unknown;\n}\n\nexport interface UseDashboardOptions extends SubscribeOptions {\n initialWidgets?: CachedWidget[];\n}\n\nexport function useDashboard(\n source: DataSource,\n dashboardId: string,\n options: UseDashboardOptions = {},\n): UseDashboardResult {\n const { initialWidgets, ...subscribeOptions } = options;\n const [widgets, setWidgets] = useState<Record<string, CachedWidget>>(() =>\n indexWidgets(initialWidgets ?? []),\n );\n const [error, setError] = useState<unknown>(null);\n const optsRef = useRef(subscribeOptions);\n optsRef.current = subscribeOptions;\n\n const initialWidgetsRef = useRef(initialWidgets);\n initialWidgetsRef.current = initialWidgets;\n\n useEffect(() => {\n setWidgets(indexWidgets(initialWidgetsRef.current ?? []));\n setError(null);\n const unsub = subscribe(\n source,\n dashboardId,\n {\n onWidgetUpdated: (w) => {\n setWidgets((prev) => ({ ...prev, [w.widgetId]: w }));\n setError(null);\n },\n onWidgetUnchanged: (w) => {\n setWidgets((prev) =>\n prev[w.widgetId] === w ? prev : { ...prev, [w.widgetId]: w },\n );\n setError(null);\n },\n onWidgetFailing: (w) => {\n setWidgets((prev) => ({ ...prev, [w.widgetId]: w }));\n setError(null);\n },\n onError: (e) => setError(e),\n },\n optsRef.current,\n );\n return unsub;\n }, [source, dashboardId]);\n\n const syncState: Record<string, WidgetSyncState | undefined> = {};\n for (const id of Object.keys(widgets)) {\n syncState[id] = widgets[id]?.syncState;\n }\n\n return { widgets, syncState, error };\n}\n\nexport interface UseWidgetResult<TData = unknown> {\n widget: CachedWidget<TData> | null;\n syncState: WidgetSyncState | undefined;\n error: unknown;\n}\n\nexport function useWidget<TData = unknown>(\n source: DataSource,\n dashboardId: string,\n widgetId: string,\n options: UseDashboardOptions = {},\n): UseWidgetResult<TData> {\n const { widgets, error } = useDashboard(source, dashboardId, options);\n const widget = (widgets[widgetId] ?? null) as CachedWidget<TData> | null;\n return { widget, syncState: widget?.syncState, error };\n}\n\nfunction indexWidgets(list: CachedWidget[]): Record<string, CachedWidget> {\n const out: Record<string, CachedWidget> = {};\n for (const w of list) {\n out[w.widgetId] = w;\n }\n return out;\n}\n"],"mappings":";;;AAGA,SAAS,iBAAiB;AAE1B,SAAS,WAAW,QAAQ,gBAAgB;AAqBrC,SAAS,aACd,QACA,aACA,UAA+B,CAAC,GACZ;AACpB,QAAM,EAAE,gBAAgB,GAAG,iBAAiB,IAAI;AAChD,QAAM,CAAC,SAAS,UAAU,IAAI;AAAA,IAAuC,MACnE,aAAa,kBAAkB,CAAC,CAAC;AAAA,EACnC;AACA,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAkB,IAAI;AAChD,QAAM,UAAU,OAAO,gBAAgB;AACvC,UAAQ,UAAU;AAElB,QAAM,oBAAoB,OAAO,cAAc;AAC/C,oBAAkB,UAAU;AAE5B,YAAU,MAAM;AACd,eAAW,aAAa,kBAAkB,WAAW,CAAC,CAAC,CAAC;AACxD,aAAS,IAAI;AACb,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,QACE,iBAAiB,CAAC,MAAM;AACtB,qBAAW,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,EAAE,QAAQ,GAAG,EAAE,EAAE;AACnD,mBAAS,IAAI;AAAA,QACf;AAAA,QACA,mBAAmB,CAAC,MAAM;AACxB;AAAA,YAAW,CAAC,SACV,KAAK,EAAE,QAAQ,MAAM,IAAI,OAAO,EAAE,GAAG,MAAM,CAAC,EAAE,QAAQ,GAAG,EAAE;AAAA,UAC7D;AACA,mBAAS,IAAI;AAAA,QACf;AAAA,QACA,iBAAiB,CAAC,MAAM;AACtB,qBAAW,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,EAAE,QAAQ,GAAG,EAAE,EAAE;AACnD,mBAAS,IAAI;AAAA,QACf;AAAA,QACA,SAAS,CAAC,MAAM,SAAS,CAAC;AAAA,MAC5B;AAAA,MACA,QAAQ;AAAA,IACV;AACA,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,WAAW,CAAC;AAExB,QAAM,YAAyD,CAAC;AAChE,aAAW,MAAM,OAAO,KAAK,OAAO,GAAG;AACrC,cAAU,EAAE,IAAI,QAAQ,EAAE,GAAG;AAAA,EAC/B;AAEA,SAAO,EAAE,SAAS,WAAW,MAAM;AACrC;AAQO,SAAS,UACd,QACA,aACA,UACA,UAA+B,CAAC,GACR;AACxB,QAAM,EAAE,SAAS,MAAM,IAAI,aAAa,QAAQ,aAAa,OAAO;AACpE,QAAM,SAAU,QAAQ,QAAQ,KAAK;AACrC,SAAO,EAAE,QAAQ,WAAW,QAAQ,WAAW,MAAM;AACvD;AAEA,SAAS,aAAa,MAAoD;AACxE,QAAM,MAAoC,CAAC;AAC3C,aAAW,KAAK,MAAM;AACpB,QAAI,EAAE,QAAQ,IAAI;AAAA,EACpB;AACA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../src/client.ts"],"sourcesContent":["'use client';\n\nimport type { CachedWidget, DataSource, WidgetSyncState } from '@rawdash/core';\nimport { subscribe } from '@rawdash/sdk-runtime';\nimport type { SubscribeOptions } from '@rawdash/sdk-runtime';\nimport { useEffect, useRef, useState } from 'react';\n\nexport type {\n SubscribeCallbacks,\n SubscribeOptions,\n Unsubscribe,\n VisibilitySource,\n} from '@rawdash/sdk-runtime';\n\nexport type { CachedWidget, DataSource, WidgetSyncState } from '@rawdash/core';\n\nexport interface UseDashboardResult {\n widgets: Record<string, CachedWidget>;\n syncState: Record<string, WidgetSyncState | undefined>;\n error: unknown;\n loading: boolean;\n}\n\nexport interface UseDashboardOptions extends SubscribeOptions {\n initialWidgets?: CachedWidget[];\n}\n\nexport function useDashboard(\n source: DataSource,\n dashboardId: string,\n options: UseDashboardOptions = {},\n): UseDashboardResult {\n const { initialWidgets, ...subscribeOptions } = options;\n const [widgets, setWidgets] = useState<Record<string, CachedWidget>>(() =>\n indexWidgets(initialWidgets ?? []),\n );\n const [error, setError] = useState<unknown>(null);\n const [loading, setLoading] = useState(\n () => (initialWidgets?.length ?? 0) === 0,\n );\n const optsRef = useRef(subscribeOptions);\n optsRef.current = subscribeOptions;\n\n const initialWidgetsRef = useRef(initialWidgets);\n initialWidgetsRef.current = initialWidgets;\n\n useEffect(() => {\n setWidgets(indexWidgets(initialWidgetsRef.current ?? []));\n setError(null);\n setLoading((initialWidgetsRef.current?.length ?? 0) === 0);\n const unsub = subscribe(\n source,\n dashboardId,\n {\n onWidgetUpdated: (w) => {\n setWidgets((prev) => ({ ...prev, [w.widgetId]: w }));\n setError(null);\n },\n onWidgetUnchanged: (w) => {\n setWidgets((prev) =>\n prev[w.widgetId] === w ? prev : { ...prev, [w.widgetId]: w },\n );\n setError(null);\n },\n onWidgetFailing: (w) => {\n setWidgets((prev) => ({ ...prev, [w.widgetId]: w }));\n setError(null);\n },\n onError: (e) => setError(e),\n onBootstrapped: () => setLoading(false),\n },\n optsRef.current,\n );\n return unsub;\n }, [source, dashboardId]);\n\n const syncState: Record<string, WidgetSyncState | undefined> = {};\n for (const id of Object.keys(widgets)) {\n syncState[id] = widgets[id]?.syncState;\n }\n\n return { widgets, syncState, error, loading };\n}\n\nexport interface UseWidgetResult<TData = unknown> {\n widget: CachedWidget<TData> | null;\n syncState: WidgetSyncState | undefined;\n error: unknown;\n loading: boolean;\n}\n\nexport function useWidget<TData = unknown>(\n source: DataSource,\n dashboardId: string,\n widgetId: string,\n options: UseDashboardOptions = {},\n): UseWidgetResult<TData> {\n const { widgets, error, loading } = useDashboard(\n source,\n dashboardId,\n options,\n );\n const widget = (widgets[widgetId] ?? null) as CachedWidget<TData> | null;\n return { widget, syncState: widget?.syncState, error, loading };\n}\n\nfunction indexWidgets(list: CachedWidget[]): Record<string, CachedWidget> {\n const out: Record<string, CachedWidget> = {};\n for (const w of list) {\n out[w.widgetId] = w;\n }\n return out;\n}\n"],"mappings":";;;AAGA,SAAS,iBAAiB;AAE1B,SAAS,WAAW,QAAQ,gBAAgB;AAsBrC,SAAS,aACd,QACA,aACA,UAA+B,CAAC,GACZ;AACpB,QAAM,EAAE,gBAAgB,GAAG,iBAAiB,IAAI;AAChD,QAAM,CAAC,SAAS,UAAU,IAAI;AAAA,IAAuC,MACnE,aAAa,kBAAkB,CAAC,CAAC;AAAA,EACnC;AACA,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAkB,IAAI;AAChD,QAAM,CAAC,SAAS,UAAU,IAAI;AAAA,IAC5B,OAAO,gBAAgB,UAAU,OAAO;AAAA,EAC1C;AACA,QAAM,UAAU,OAAO,gBAAgB;AACvC,UAAQ,UAAU;AAElB,QAAM,oBAAoB,OAAO,cAAc;AAC/C,oBAAkB,UAAU;AAE5B,YAAU,MAAM;AACd,eAAW,aAAa,kBAAkB,WAAW,CAAC,CAAC,CAAC;AACxD,aAAS,IAAI;AACb,gBAAY,kBAAkB,SAAS,UAAU,OAAO,CAAC;AACzD,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,QACE,iBAAiB,CAAC,MAAM;AACtB,qBAAW,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,EAAE,QAAQ,GAAG,EAAE,EAAE;AACnD,mBAAS,IAAI;AAAA,QACf;AAAA,QACA,mBAAmB,CAAC,MAAM;AACxB;AAAA,YAAW,CAAC,SACV,KAAK,EAAE,QAAQ,MAAM,IAAI,OAAO,EAAE,GAAG,MAAM,CAAC,EAAE,QAAQ,GAAG,EAAE;AAAA,UAC7D;AACA,mBAAS,IAAI;AAAA,QACf;AAAA,QACA,iBAAiB,CAAC,MAAM;AACtB,qBAAW,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,EAAE,QAAQ,GAAG,EAAE,EAAE;AACnD,mBAAS,IAAI;AAAA,QACf;AAAA,QACA,SAAS,CAAC,MAAM,SAAS,CAAC;AAAA,QAC1B,gBAAgB,MAAM,WAAW,KAAK;AAAA,MACxC;AAAA,MACA,QAAQ;AAAA,IACV;AACA,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,WAAW,CAAC;AAExB,QAAM,YAAyD,CAAC;AAChE,aAAW,MAAM,OAAO,KAAK,OAAO,GAAG;AACrC,cAAU,EAAE,IAAI,QAAQ,EAAE,GAAG;AAAA,EAC/B;AAEA,SAAO,EAAE,SAAS,WAAW,OAAO,QAAQ;AAC9C;AASO,SAAS,UACd,QACA,aACA,UACA,UAA+B,CAAC,GACR;AACxB,QAAM,EAAE,SAAS,OAAO,QAAQ,IAAI;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,SAAU,QAAQ,QAAQ,KAAK;AACrC,SAAO,EAAE,QAAQ,WAAW,QAAQ,WAAW,OAAO,QAAQ;AAChE;AAEA,SAAS,aAAa,MAAoD;AACxE,QAAM,MAAoC,CAAC;AAC3C,aAAW,KAAK,MAAM;AACpB,QAAI,EAAE,QAAQ,IAAI;AAAA,EACpB;AACA,SAAO;AACT;","names":[]}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { DataSource } from '@rawdash/core';
2
- export { ACTIVE_SYNC_STATUSES, CachedWidget, DataSource, HealthResponse, SyncState, SyncStatus, TriggerSyncResponse, WidgetSyncState, WidgetsListResponse, isSyncActive } from '@rawdash/core';
2
+ export { ACTIVE_SYNC_STATUSES, CachedWidget, DataSource, HealthResponse, MergeSeriesOptions, MergedPoint, SyncState, SyncStatus, TriggerSyncResponse, WidgetSeries, WidgetSyncState, WidgetsListResponse, isSyncActive, mergeSeries, mergeSeriesScalar } from '@rawdash/core';
3
3
  import { HttpOptions } from '@rawdash/sdk-client';
4
4
  export { HttpOptions } from '@rawdash/sdk-client';
5
5
 
package/dist/index.js CHANGED
@@ -2,7 +2,12 @@
2
2
  import { isSyncActive } from "@rawdash/core";
3
3
  import { http as clientHttp } from "@rawdash/sdk-client";
4
4
  import { revalidateTag } from "next/cache";
5
- import { ACTIVE_SYNC_STATUSES, isSyncActive as isSyncActive2 } from "@rawdash/core";
5
+ import {
6
+ ACTIVE_SYNC_STATUSES,
7
+ isSyncActive as isSyncActive2,
8
+ mergeSeries,
9
+ mergeSeriesScalar
10
+ } from "@rawdash/core";
6
11
  var RAWDASH_CACHE_TAG = "rawdash";
7
12
  function http(opts) {
8
13
  const taggedFetch = (input, init) => {
@@ -67,6 +72,8 @@ export {
67
72
  ACTIVE_SYNC_STATUSES,
68
73
  createRawdashClient,
69
74
  http,
70
- isSyncActive2 as isSyncActive
75
+ isSyncActive2 as isSyncActive,
76
+ mergeSeries,
77
+ mergeSeriesScalar
71
78
  };
72
79
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { DataSource } from '@rawdash/core';\nimport { isSyncActive } from '@rawdash/core';\nimport { http as clientHttp } from '@rawdash/sdk-client';\nimport type { HttpOptions } from '@rawdash/sdk-client';\nimport { revalidateTag } from 'next/cache';\n\nexport type { HttpOptions } from '@rawdash/sdk-client';\n\nexport type {\n CachedWidget,\n DataSource,\n HealthResponse,\n SyncState,\n SyncStatus,\n TriggerSyncResponse,\n WidgetSyncState,\n WidgetsListResponse,\n} from '@rawdash/core';\n\nexport { ACTIVE_SYNC_STATUSES, isSyncActive } from '@rawdash/core';\n\nconst RAWDASH_CACHE_TAG = 'rawdash';\n\ntype NextFetchInit = RequestInit & {\n next?: {\n revalidate?: number | false;\n tags?: string[];\n };\n};\n\nexport function http(opts: HttpOptions): DataSource {\n const taggedFetch: typeof globalThis.fetch = (input, init) => {\n return globalThis.fetch(\n input as RequestInfo,\n {\n ...(init as NextFetchInit),\n next: {\n ...(init as NextFetchInit | undefined)?.next,\n tags: [\n ...((init as NextFetchInit | undefined)?.next?.tags ?? []),\n RAWDASH_CACHE_TAG,\n ],\n },\n } as RequestInit,\n );\n };\n return clientHttp({ ...opts, fetch: taggedFetch });\n}\n\nconst DEFAULT_SYNC_TIMEOUT_MS = 30_000;\nconst DEFAULT_SYNC_POLL_INTERVAL_MS = 500;\n\nexport function createRawdashClient(dataSource: DataSource): DataSource {\n return {\n getWidget: (dashboardId, widgetId) =>\n dataSource.getWidget(dashboardId, widgetId),\n\n getWidgets: (dashboardId) => dataSource.getWidgets(dashboardId),\n\n getHealth: () => dataSource.getHealth(),\n\n getSyncState: () => dataSource.getSyncState(),\n\n async ensureFresh(maxAgeMs) {\n const synced = await dataSource.ensureFresh(maxAgeMs);\n if (synced) {\n revalidateTag(RAWDASH_CACHE_TAG);\n }\n return synced;\n },\n\n async triggerSync() {\n const result = await dataSource.triggerSync();\n\n const deadline = Date.now() + DEFAULT_SYNC_TIMEOUT_MS;\n for (;;) {\n const state = await dataSource.getSyncState();\n if (!isSyncActive(state.status)) {\n if (state.status === 'failed') {\n throw new Error(\n `Rawdash sync failed: ${state.lastError ?? 'unknown error'}`,\n );\n }\n revalidateTag(RAWDASH_CACHE_TAG);\n return result;\n }\n if (Date.now() >= deadline) {\n throw new Error(\n `Rawdash sync did not settle within ${DEFAULT_SYNC_TIMEOUT_MS}ms (last status: ${state.status})`,\n );\n }\n await new Promise<void>((resolve) =>\n setTimeout(resolve, DEFAULT_SYNC_POLL_INTERVAL_MS),\n );\n }\n },\n };\n}\n"],"mappings":";AACA,SAAS,oBAAoB;AAC7B,SAAS,QAAQ,kBAAkB;AAEnC,SAAS,qBAAqB;AAe9B,SAAS,sBAAsB,gBAAAA,qBAAoB;AAEnD,IAAM,oBAAoB;AASnB,SAAS,KAAK,MAA+B;AAClD,QAAM,cAAuC,CAAC,OAAO,SAAS;AAC5D,WAAO,WAAW;AAAA,MAChB;AAAA,MACA;AAAA,QACE,GAAI;AAAA,QACJ,MAAM;AAAA,UACJ,GAAI,MAAoC;AAAA,UACxC,MAAM;AAAA,YACJ,GAAK,MAAoC,MAAM,QAAQ,CAAC;AAAA,YACxD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO,WAAW,EAAE,GAAG,MAAM,OAAO,YAAY,CAAC;AACnD;AAEA,IAAM,0BAA0B;AAChC,IAAM,gCAAgC;AAE/B,SAAS,oBAAoB,YAAoC;AACtE,SAAO;AAAA,IACL,WAAW,CAAC,aAAa,aACvB,WAAW,UAAU,aAAa,QAAQ;AAAA,IAE5C,YAAY,CAAC,gBAAgB,WAAW,WAAW,WAAW;AAAA,IAE9D,WAAW,MAAM,WAAW,UAAU;AAAA,IAEtC,cAAc,MAAM,WAAW,aAAa;AAAA,IAE5C,MAAM,YAAY,UAAU;AAC1B,YAAM,SAAS,MAAM,WAAW,YAAY,QAAQ;AACpD,UAAI,QAAQ;AACV,sBAAc,iBAAiB;AAAA,MACjC;AACA,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,cAAc;AAClB,YAAM,SAAS,MAAM,WAAW,YAAY;AAE5C,YAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,iBAAS;AACP,cAAM,QAAQ,MAAM,WAAW,aAAa;AAC5C,YAAI,CAAC,aAAa,MAAM,MAAM,GAAG;AAC/B,cAAI,MAAM,WAAW,UAAU;AAC7B,kBAAM,IAAI;AAAA,cACR,wBAAwB,MAAM,aAAa,eAAe;AAAA,YAC5D;AAAA,UACF;AACA,wBAAc,iBAAiB;AAC/B,iBAAO;AAAA,QACT;AACA,YAAI,KAAK,IAAI,KAAK,UAAU;AAC1B,gBAAM,IAAI;AAAA,YACR,sCAAsC,uBAAuB,oBAAoB,MAAM,MAAM;AAAA,UAC/F;AAAA,QACF;AACA,cAAM,IAAI;AAAA,UAAc,CAAC,YACvB,WAAW,SAAS,6BAA6B;AAAA,QACnD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":["isSyncActive"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { DataSource } from '@rawdash/core';\nimport { isSyncActive } from '@rawdash/core';\nimport { http as clientHttp } from '@rawdash/sdk-client';\nimport type { HttpOptions } from '@rawdash/sdk-client';\nimport { revalidateTag } from 'next/cache';\n\nexport type { HttpOptions } from '@rawdash/sdk-client';\n\nexport type {\n CachedWidget,\n DataSource,\n HealthResponse,\n MergedPoint,\n MergeSeriesOptions,\n SyncState,\n SyncStatus,\n TriggerSyncResponse,\n WidgetSeries,\n WidgetSyncState,\n WidgetsListResponse,\n} from '@rawdash/core';\n\nexport {\n ACTIVE_SYNC_STATUSES,\n isSyncActive,\n mergeSeries,\n mergeSeriesScalar,\n} from '@rawdash/core';\n\nconst RAWDASH_CACHE_TAG = 'rawdash';\n\ntype NextFetchInit = RequestInit & {\n next?: {\n revalidate?: number | false;\n tags?: string[];\n };\n};\n\nexport function http(opts: HttpOptions): DataSource {\n const taggedFetch: typeof globalThis.fetch = (input, init) => {\n return globalThis.fetch(\n input as RequestInfo,\n {\n ...(init as NextFetchInit),\n next: {\n ...(init as NextFetchInit | undefined)?.next,\n tags: [\n ...((init as NextFetchInit | undefined)?.next?.tags ?? []),\n RAWDASH_CACHE_TAG,\n ],\n },\n } as RequestInit,\n );\n };\n return clientHttp({ ...opts, fetch: taggedFetch });\n}\n\nconst DEFAULT_SYNC_TIMEOUT_MS = 30_000;\nconst DEFAULT_SYNC_POLL_INTERVAL_MS = 500;\n\nexport function createRawdashClient(dataSource: DataSource): DataSource {\n return {\n getWidget: (dashboardId, widgetId) =>\n dataSource.getWidget(dashboardId, widgetId),\n\n getWidgets: (dashboardId) => dataSource.getWidgets(dashboardId),\n\n getHealth: () => dataSource.getHealth(),\n\n getSyncState: () => dataSource.getSyncState(),\n\n async ensureFresh(maxAgeMs) {\n const synced = await dataSource.ensureFresh(maxAgeMs);\n if (synced) {\n revalidateTag(RAWDASH_CACHE_TAG);\n }\n return synced;\n },\n\n async triggerSync() {\n const result = await dataSource.triggerSync();\n\n const deadline = Date.now() + DEFAULT_SYNC_TIMEOUT_MS;\n for (;;) {\n const state = await dataSource.getSyncState();\n if (!isSyncActive(state.status)) {\n if (state.status === 'failed') {\n throw new Error(\n `Rawdash sync failed: ${state.lastError ?? 'unknown error'}`,\n );\n }\n revalidateTag(RAWDASH_CACHE_TAG);\n return result;\n }\n if (Date.now() >= deadline) {\n throw new Error(\n `Rawdash sync did not settle within ${DEFAULT_SYNC_TIMEOUT_MS}ms (last status: ${state.status})`,\n );\n }\n await new Promise<void>((resolve) =>\n setTimeout(resolve, DEFAULT_SYNC_POLL_INTERVAL_MS),\n );\n }\n },\n };\n}\n"],"mappings":";AACA,SAAS,oBAAoB;AAC7B,SAAS,QAAQ,kBAAkB;AAEnC,SAAS,qBAAqB;AAkB9B;AAAA,EACE;AAAA,EACA,gBAAAA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,IAAM,oBAAoB;AASnB,SAAS,KAAK,MAA+B;AAClD,QAAM,cAAuC,CAAC,OAAO,SAAS;AAC5D,WAAO,WAAW;AAAA,MAChB;AAAA,MACA;AAAA,QACE,GAAI;AAAA,QACJ,MAAM;AAAA,UACJ,GAAI,MAAoC;AAAA,UACxC,MAAM;AAAA,YACJ,GAAK,MAAoC,MAAM,QAAQ,CAAC;AAAA,YACxD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO,WAAW,EAAE,GAAG,MAAM,OAAO,YAAY,CAAC;AACnD;AAEA,IAAM,0BAA0B;AAChC,IAAM,gCAAgC;AAE/B,SAAS,oBAAoB,YAAoC;AACtE,SAAO;AAAA,IACL,WAAW,CAAC,aAAa,aACvB,WAAW,UAAU,aAAa,QAAQ;AAAA,IAE5C,YAAY,CAAC,gBAAgB,WAAW,WAAW,WAAW;AAAA,IAE9D,WAAW,MAAM,WAAW,UAAU;AAAA,IAEtC,cAAc,MAAM,WAAW,aAAa;AAAA,IAE5C,MAAM,YAAY,UAAU;AAC1B,YAAM,SAAS,MAAM,WAAW,YAAY,QAAQ;AACpD,UAAI,QAAQ;AACV,sBAAc,iBAAiB;AAAA,MACjC;AACA,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,cAAc;AAClB,YAAM,SAAS,MAAM,WAAW,YAAY;AAE5C,YAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,iBAAS;AACP,cAAM,QAAQ,MAAM,WAAW,aAAa;AAC5C,YAAI,CAAC,aAAa,MAAM,MAAM,GAAG;AAC/B,cAAI,MAAM,WAAW,UAAU;AAC7B,kBAAM,IAAI;AAAA,cACR,wBAAwB,MAAM,aAAa,eAAe;AAAA,YAC5D;AAAA,UACF;AACA,wBAAc,iBAAiB;AAC/B,iBAAO;AAAA,QACT;AACA,YAAI,KAAK,IAAI,KAAK,UAAU;AAC1B,gBAAM,IAAI;AAAA,YACR,sCAAsC,uBAAuB,oBAAoB,MAAM,MAAM;AAAA,UAC/F;AAAA,QACF;AACA,cAAM,IAAI;AAAA,UAAc,CAAC,YACvB,WAAW,SAAS,6BAA6B;AAAA,QACnD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":["isSyncActive"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rawdash/sdk-nextjs",
3
- "version": "0.27.0",
3
+ "version": "0.28.2",
4
4
  "description": "Rawdash client SDK for Next.js App Router (Server Components and Server Actions)",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -32,9 +32,9 @@
32
32
  }
33
33
  },
34
34
  "dependencies": {
35
- "@rawdash/sdk-client": "0.27.0",
36
- "@rawdash/sdk-runtime": "0.27.0",
37
- "@rawdash/core": "0.27.0"
35
+ "@rawdash/sdk-runtime": "0.28.2",
36
+ "@rawdash/sdk-client": "0.28.2",
37
+ "@rawdash/core": "0.28.2"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "next": ">=14.0.0",