@rawdash/server 0.10.1 → 0.11.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 CHANGED
@@ -1,5 +1,5 @@
1
- import { ServerStorage, DashboardConfig, CachedWidget } from '@rawdash/core';
2
- export { CachedWidget, DashboardConfig, InMemoryStorage, ServerStorage, SyncState, computeMetric } from '@rawdash/core';
1
+ import { ServerStorage, DashboardConfig, CachedWidget, SyncState, TriggerSyncResponse } from '@rawdash/core';
2
+ export { DashboardConfig, InMemoryStorage, ServerStorage, computeMetric } from '@rawdash/core';
3
3
  import { Hono } from 'hono';
4
4
 
5
5
  interface ServeOptions {
@@ -21,14 +21,8 @@ interface EngineOptions {
21
21
  interface Engine {
22
22
  getWidget(dashboardId: string, widgetId: string): Promise<CachedWidget | undefined>;
23
23
  getWidgets(dashboardId: string): Promise<CachedWidget[]>;
24
- getHealth(): Promise<{
25
- status: 'idle' | 'syncing' | 'error';
26
- lastSyncAt: string | null;
27
- lastError: string | null;
28
- }>;
29
- triggerSync(): Promise<{
30
- triggered: boolean;
31
- }>;
24
+ getHealth(): Promise<SyncState>;
25
+ triggerSync(): Promise<TriggerSyncResponse>;
32
26
  }
33
27
  declare function createEngine(config: DashboardConfig, options?: EngineOptions): Engine;
34
28
 
package/dist/index.js CHANGED
@@ -216,7 +216,8 @@ var WidgetsRouter = class {
216
216
  const widgets = resolved.filter(
217
217
  (w) => w !== void 0
218
218
  );
219
- return c.json(widgets);
219
+ const response = { widgets };
220
+ return c.json(response);
220
221
  });
221
222
  app.get(`${base}/:widgetId`, async (c) => {
222
223
  const widgetId = c.req.param("widgetId");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/routers/health.ts","../src/routers/retention.ts","../src/routers/sync.ts","../src/routers/widgets.ts","../src/storage.ts","../src/engine-router.ts","../src/server.ts","../src/engine.ts","../src/compute.ts"],"sourcesContent":["import { serve as honoServe } from '@hono/node-server';\n\nimport { createEngineRouters } from './engine-router';\nimport { createServer } from './server';\nimport type { DashboardConfig, ServeOptions } from './types';\n\nexport { createServer } from './server';\nexport { createEngineRouters } from './engine-router';\nexport { createEngine } from './engine';\nexport { computeMetric } from './compute';\nexport { InMemoryStorage } from './storage';\nexport type { RouterMount } from './router';\nexport type { SyncState, CachedWidget } from '@rawdash/core';\nexport type { DashboardConfig, ServeOptions, ServerStorage } from './types';\nexport type { Engine, EngineOptions } from './engine';\n\nexport function serve(\n config: DashboardConfig,\n options: ServeOptions = {},\n): void {\n const { port = 8080, storage } = options;\n const app = createServer(createEngineRouters(config, storage));\n honoServe({ fetch: app.fetch, port });\n}\n","import type { Hono } from 'hono';\n\nimport type { RouterMount } from '../router';\nimport type { ServerStorage } from '../types';\n\nexport class HealthRouter implements RouterMount {\n constructor(private storage: ServerStorage) {}\n\n mount(app: Hono): void {\n app.get('/health', async (c) => {\n return c.json(await this.storage.getSyncState());\n });\n }\n}\n","import type { DashboardConfig, RetentionConfig } from '@rawdash/core';\nimport { selectForDeletion } from '@rawdash/core';\nimport type { Hono } from 'hono';\n\nimport type { RouterMount } from '../router';\nimport type { ServerStorage } from '../types';\n\nconst DEFAULT_INTERVAL_MS = 60 * 60 * 1000; // 1 hour\n\nfunction hasPruningPolicy(config: RetentionConfig): boolean {\n return config.maxAge !== undefined || config.maxSize !== undefined;\n}\n\nexport class RetentionRouter implements RouterMount {\n private interval: ReturnType<typeof setInterval> | null = null;\n private inFlight: Promise<void> | null = null;\n\n constructor(\n private config: DashboardConfig,\n private storage: ServerStorage,\n ) {}\n\n async runRetention(): Promise<void> {\n if (this.inFlight) {\n return this.inFlight;\n }\n\n this.inFlight = this.runRetentionOnce().finally(() => {\n this.inFlight = null;\n });\n\n return this.inFlight;\n }\n\n private async runRetentionOnce(): Promise<void> {\n const retentionConfig = this.config.retention;\n if (!retentionConfig || !hasPruningPolicy(retentionConfig)) {\n return;\n }\n\n const nowMs = Date.now();\n\n const results = await Promise.allSettled(\n this.config.connectors.map(async ({ connector }) => {\n const handle = this.storage.getStorageHandle(connector.id);\n\n const [events, metrics, distributions] = await Promise.all([\n handle.queryEvents({}),\n handle.queryMetrics({}),\n handle.queryDistributions({}),\n ]);\n\n await applyRetentionToShape(\n events,\n (e) => e.start_ts,\n retentionConfig,\n nowMs,\n (survivors, names) => handle.events(survivors, { names }),\n );\n\n await applyRetentionToShape(\n metrics,\n (m) => m.ts,\n retentionConfig,\n nowMs,\n (survivors, names) => handle.metrics(survivors, { names }),\n );\n\n await applyRetentionToShape(\n distributions,\n (d) => d.ts,\n retentionConfig,\n nowMs,\n (survivors, names) => handle.distributions(survivors, { names }),\n );\n }),\n );\n\n const failures = results.filter(\n (r): r is PromiseRejectedResult => r.status === 'rejected',\n );\n if (failures.length > 0) {\n throw new Error(\n `Retention failed for ${failures.length} connector(s): ${failures.map((f) => String(f.reason)).join('; ')}`,\n );\n }\n }\n\n mount(app: Hono): void {\n app.post('/retain', async (c) => {\n try {\n await this.runRetention();\n return c.json({ triggered: true });\n } catch (err) {\n console.error('retention run failed', err);\n return c.json({ triggered: false }, 500);\n }\n });\n\n const retentionConfig = this.config.retention;\n if (retentionConfig && hasPruningPolicy(retentionConfig)) {\n const intervalMs = retentionConfig.intervalMs ?? DEFAULT_INTERVAL_MS;\n this.interval = setInterval(() => {\n void this.runRetention().catch((err) => {\n console.error('retention run failed', err);\n });\n }, intervalMs);\n }\n }\n\n stop(): void {\n if (this.interval !== null) {\n clearInterval(this.interval);\n this.interval = null;\n }\n }\n}\n\nasync function applyRetentionToShape<T extends { name: string }>(\n rows: T[],\n getTs: (row: T) => number,\n config: RetentionConfig,\n nowMs: number,\n writeSurvivors: (survivors: T[], names: string[]) => Promise<void>,\n): Promise<void> {\n if (rows.length === 0) {\n return;\n }\n\n const sorted = [...rows].sort((a, b) => getTs(b) - getTs(a));\n const toDeleteSet = new Set(selectForDeletion(sorted, getTs, config, nowMs));\n\n if (toDeleteSet.size === 0) {\n return;\n }\n\n const survivors = sorted.filter((r) => !toDeleteSet.has(r));\n const allNames = [...new Set(rows.map((r) => r.name))];\n\n await writeSurvivors(survivors, allNames);\n}\n","import type { DashboardConfig } from '@rawdash/core';\nimport type { Hono } from 'hono';\n\nimport type { RouterMount } from '../router';\nimport type { ServerStorage } from '../types';\n\nconst FULL_SYNC_TIMEOUT_MS = 300_000;\n\nexport class SyncRouter implements RouterMount {\n constructor(\n private config: DashboardConfig,\n private storage: ServerStorage,\n ) {}\n\n async runSync(): Promise<void> {\n const acquired = await this.storage.setSyncing();\n if (!acquired) {\n return;\n }\n const errors: string[] = [];\n await Promise.allSettled(\n this.config.connectors.map(async ({ connector }) => {\n const handle = this.storage.getStorageHandle(connector.id);\n const controller = new AbortController();\n const timer = setTimeout(\n () => controller.abort(),\n FULL_SYNC_TIMEOUT_MS,\n );\n try {\n const result = await connector.sync(\n { mode: 'full' },\n handle,\n controller.signal,\n );\n if (!result.done) {\n errors.push(\n `${connector.id} did not complete in one chunk (chunked syncs are only supported in cloud)`,\n );\n }\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n errors.push(\n `${connector.id} timed out after ${FULL_SYNC_TIMEOUT_MS}ms`,\n );\n } else {\n errors.push(err instanceof Error ? err.message : String(err));\n }\n } finally {\n clearTimeout(timer);\n }\n }),\n );\n if (errors.length > 0) {\n await this.storage.setSyncError(errors.join('; '));\n } else {\n await this.storage.setSyncSuccess();\n }\n }\n\n mount(app: Hono): void {\n app.post('/sync', async (c) => {\n const state = await this.storage.getSyncState();\n if (state.status === 'syncing') {\n return c.json({ triggered: false });\n }\n void this.runSync();\n return c.json({ triggered: true });\n });\n }\n}\n","import type {\n CachedWidget,\n ConfiguredConnector,\n Dashboard,\n Widget,\n} from '@rawdash/core';\nimport { resolveWidget } from '@rawdash/core';\nimport type { Hono } from 'hono';\n\nimport type { RouterMount } from '../router';\nimport type { ServerStorage } from '../types';\n\nexport class WidgetsRouter implements RouterMount {\n constructor(\n private dashboardId: string,\n private dashboard: Dashboard,\n private connectors: ConfiguredConnector[],\n private storage: ServerStorage,\n ) {}\n\n private resolve(\n id: string,\n widget: Widget,\n ): Promise<CachedWidget | undefined> {\n return resolveWidget(id, widget, this.connectors, this.storage);\n }\n\n mount(app: Hono): void {\n const base = `/dashboards/${this.dashboardId}/widgets`;\n\n app.get(base, async (c) => {\n const entries = Object.entries(this.dashboard.widgets);\n const resolved = await Promise.all(\n entries.map(([key, widget]) => this.resolve(key, widget)),\n );\n const widgets = resolved.filter(\n (w): w is CachedWidget => w !== undefined,\n );\n return c.json(widgets);\n });\n\n app.get(`${base}/:widgetId`, async (c) => {\n const widgetId = c.req.param('widgetId');\n const widget = this.dashboard.widgets[widgetId];\n if (!widget) {\n return c.json({ error: 'Widget not found' }, 404);\n }\n const result = await this.resolve(widgetId, widget);\n if (!result) {\n return c.json({ error: 'Widget not found' }, 404);\n }\n return c.json(result);\n });\n }\n}\n","export { InMemoryStorage } from '@rawdash/core';\n","import type { DashboardConfig } from '@rawdash/core';\n\nimport type { RouterMount } from './router';\nimport { HealthRouter } from './routers/health';\nimport { RetentionRouter } from './routers/retention';\nimport { SyncRouter } from './routers/sync';\nimport { WidgetsRouter } from './routers/widgets';\nimport { InMemoryStorage } from './storage';\nimport type { ServerStorage } from './types';\n\nexport function createEngineRouters(\n config: DashboardConfig,\n storage: ServerStorage = new InMemoryStorage(),\n): RouterMount[] {\n const widgetRouters = Object.entries(config.dashboards).map(\n ([dashboardId, dashboard]) =>\n new WidgetsRouter(dashboardId, dashboard, config.connectors, storage),\n );\n\n return [\n ...widgetRouters,\n new SyncRouter(config, storage),\n new RetentionRouter(config, storage),\n new HealthRouter(storage),\n ];\n}\n","import { Hono } from 'hono';\n\nimport type { RouterMount } from './router';\n\nexport function createServer(routers: RouterMount[]): Hono {\n const app = new Hono();\n for (const router of routers) {\n router.mount(app);\n }\n return app;\n}\n","import type { CachedWidget, DashboardConfig } from '@rawdash/core';\nimport { InMemoryStorage, resolveWidget } from '@rawdash/core';\n\nimport { SyncRouter } from './routers/sync';\nimport type { ServerStorage } from './types';\n\nexport interface EngineOptions {\n storage?: ServerStorage;\n}\n\nexport interface Engine {\n getWidget(\n dashboardId: string,\n widgetId: string,\n ): Promise<CachedWidget | undefined>;\n getWidgets(dashboardId: string): Promise<CachedWidget[]>;\n getHealth(): Promise<{\n status: 'idle' | 'syncing' | 'error';\n lastSyncAt: string | null;\n lastError: string | null;\n }>;\n triggerSync(): Promise<{ triggered: boolean }>;\n}\n\nexport function createEngine(\n config: DashboardConfig,\n options: EngineOptions = {},\n): Engine {\n const storage: ServerStorage = options.storage ?? new InMemoryStorage();\n const syncRouter = new SyncRouter(config, storage);\n\n return {\n async getWidget(dashboardId, widgetId) {\n const dashboard = config.dashboards[dashboardId];\n if (!dashboard) {\n return undefined;\n }\n const widget = dashboard.widgets[widgetId];\n if (!widget) {\n return undefined;\n }\n return resolveWidget(widgetId, widget, config.connectors, storage);\n },\n\n async getWidgets(dashboardId) {\n const dashboard = config.dashboards[dashboardId];\n if (!dashboard) {\n return [];\n }\n const entries = Object.entries(dashboard.widgets);\n const resolved = await Promise.all(\n entries.map(([key, widget]) =>\n resolveWidget(key, widget, config.connectors, storage),\n ),\n );\n return resolved.filter((w): w is CachedWidget => w !== undefined);\n },\n\n async getHealth() {\n return storage.getSyncState();\n },\n\n async triggerSync() {\n const state = await storage.getSyncState();\n if (state.status === 'syncing') {\n return { triggered: false };\n }\n void syncRouter.runSync().catch((error) => {\n console.error('Rawdash sync failed', error);\n });\n return { triggered: true };\n },\n };\n}\n","export { computeMetric } from '@rawdash/core';\n"],"mappings":"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","names":["InMemoryStorage","resolveWidget","InMemoryStorage","resolveWidget"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/routers/health.ts","../src/routers/retention.ts","../src/routers/sync.ts","../src/routers/widgets.ts","../src/storage.ts","../src/engine-router.ts","../src/server.ts","../src/engine.ts","../src/compute.ts"],"sourcesContent":["import { serve as honoServe } from '@hono/node-server';\n\nimport { createEngineRouters } from './engine-router';\nimport { createServer } from './server';\nimport type { DashboardConfig, ServeOptions } from './types';\n\nexport { createServer } from './server';\nexport { createEngineRouters } from './engine-router';\nexport { createEngine } from './engine';\nexport { computeMetric } from './compute';\nexport { InMemoryStorage } from './storage';\nexport type { RouterMount } from './router';\nexport type { DashboardConfig, ServeOptions, ServerStorage } from './types';\nexport type { Engine, EngineOptions } from './engine';\n\nexport function serve(\n config: DashboardConfig,\n options: ServeOptions = {},\n): void {\n const { port = 8080, storage } = options;\n const app = createServer(createEngineRouters(config, storage));\n honoServe({ fetch: app.fetch, port });\n}\n","import type { Hono } from 'hono';\n\nimport type { RouterMount } from '../router';\nimport type { ServerStorage } from '../types';\n\nexport class HealthRouter implements RouterMount {\n constructor(private storage: ServerStorage) {}\n\n mount(app: Hono): void {\n app.get('/health', async (c) => {\n return c.json(await this.storage.getSyncState());\n });\n }\n}\n","import type { DashboardConfig, RetentionConfig } from '@rawdash/core';\nimport { selectForDeletion } from '@rawdash/core';\nimport type { Hono } from 'hono';\n\nimport type { RouterMount } from '../router';\nimport type { ServerStorage } from '../types';\n\nconst DEFAULT_INTERVAL_MS = 60 * 60 * 1000; // 1 hour\n\nfunction hasPruningPolicy(config: RetentionConfig): boolean {\n return config.maxAge !== undefined || config.maxSize !== undefined;\n}\n\nexport class RetentionRouter implements RouterMount {\n private interval: ReturnType<typeof setInterval> | null = null;\n private inFlight: Promise<void> | null = null;\n\n constructor(\n private config: DashboardConfig,\n private storage: ServerStorage,\n ) {}\n\n async runRetention(): Promise<void> {\n if (this.inFlight) {\n return this.inFlight;\n }\n\n this.inFlight = this.runRetentionOnce().finally(() => {\n this.inFlight = null;\n });\n\n return this.inFlight;\n }\n\n private async runRetentionOnce(): Promise<void> {\n const retentionConfig = this.config.retention;\n if (!retentionConfig || !hasPruningPolicy(retentionConfig)) {\n return;\n }\n\n const nowMs = Date.now();\n\n const results = await Promise.allSettled(\n this.config.connectors.map(async ({ connector }) => {\n const handle = this.storage.getStorageHandle(connector.id);\n\n const [events, metrics, distributions] = await Promise.all([\n handle.queryEvents({}),\n handle.queryMetrics({}),\n handle.queryDistributions({}),\n ]);\n\n await applyRetentionToShape(\n events,\n (e) => e.start_ts,\n retentionConfig,\n nowMs,\n (survivors, names) => handle.events(survivors, { names }),\n );\n\n await applyRetentionToShape(\n metrics,\n (m) => m.ts,\n retentionConfig,\n nowMs,\n (survivors, names) => handle.metrics(survivors, { names }),\n );\n\n await applyRetentionToShape(\n distributions,\n (d) => d.ts,\n retentionConfig,\n nowMs,\n (survivors, names) => handle.distributions(survivors, { names }),\n );\n }),\n );\n\n const failures = results.filter(\n (r): r is PromiseRejectedResult => r.status === 'rejected',\n );\n if (failures.length > 0) {\n throw new Error(\n `Retention failed for ${failures.length} connector(s): ${failures.map((f) => String(f.reason)).join('; ')}`,\n );\n }\n }\n\n mount(app: Hono): void {\n app.post('/retain', async (c) => {\n try {\n await this.runRetention();\n return c.json({ triggered: true });\n } catch (err) {\n console.error('retention run failed', err);\n return c.json({ triggered: false }, 500);\n }\n });\n\n const retentionConfig = this.config.retention;\n if (retentionConfig && hasPruningPolicy(retentionConfig)) {\n const intervalMs = retentionConfig.intervalMs ?? DEFAULT_INTERVAL_MS;\n this.interval = setInterval(() => {\n void this.runRetention().catch((err) => {\n console.error('retention run failed', err);\n });\n }, intervalMs);\n }\n }\n\n stop(): void {\n if (this.interval !== null) {\n clearInterval(this.interval);\n this.interval = null;\n }\n }\n}\n\nasync function applyRetentionToShape<T extends { name: string }>(\n rows: T[],\n getTs: (row: T) => number,\n config: RetentionConfig,\n nowMs: number,\n writeSurvivors: (survivors: T[], names: string[]) => Promise<void>,\n): Promise<void> {\n if (rows.length === 0) {\n return;\n }\n\n const sorted = [...rows].sort((a, b) => getTs(b) - getTs(a));\n const toDeleteSet = new Set(selectForDeletion(sorted, getTs, config, nowMs));\n\n if (toDeleteSet.size === 0) {\n return;\n }\n\n const survivors = sorted.filter((r) => !toDeleteSet.has(r));\n const allNames = [...new Set(rows.map((r) => r.name))];\n\n await writeSurvivors(survivors, allNames);\n}\n","import type { DashboardConfig } from '@rawdash/core';\nimport type { Hono } from 'hono';\n\nimport type { RouterMount } from '../router';\nimport type { ServerStorage } from '../types';\n\nconst FULL_SYNC_TIMEOUT_MS = 300_000;\n\nexport class SyncRouter implements RouterMount {\n constructor(\n private config: DashboardConfig,\n private storage: ServerStorage,\n ) {}\n\n async runSync(): Promise<void> {\n const acquired = await this.storage.setSyncing();\n if (!acquired) {\n return;\n }\n const errors: string[] = [];\n await Promise.allSettled(\n this.config.connectors.map(async ({ connector }) => {\n const handle = this.storage.getStorageHandle(connector.id);\n const controller = new AbortController();\n const timer = setTimeout(\n () => controller.abort(),\n FULL_SYNC_TIMEOUT_MS,\n );\n try {\n const result = await connector.sync(\n { mode: 'full' },\n handle,\n controller.signal,\n );\n if (!result.done) {\n errors.push(\n `${connector.id} did not complete in one chunk (chunked syncs are only supported in cloud)`,\n );\n }\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n errors.push(\n `${connector.id} timed out after ${FULL_SYNC_TIMEOUT_MS}ms`,\n );\n } else {\n errors.push(err instanceof Error ? err.message : String(err));\n }\n } finally {\n clearTimeout(timer);\n }\n }),\n );\n if (errors.length > 0) {\n await this.storage.setSyncError(errors.join('; '));\n } else {\n await this.storage.setSyncSuccess();\n }\n }\n\n mount(app: Hono): void {\n app.post('/sync', async (c) => {\n const state = await this.storage.getSyncState();\n if (state.status === 'syncing') {\n return c.json({ triggered: false });\n }\n void this.runSync();\n return c.json({ triggered: true });\n });\n }\n}\n","import type {\n CachedWidget,\n ConfiguredConnector,\n Dashboard,\n Widget,\n WidgetsListResponse,\n} from '@rawdash/core';\nimport { resolveWidget } from '@rawdash/core';\nimport type { Hono } from 'hono';\n\nimport type { RouterMount } from '../router';\nimport type { ServerStorage } from '../types';\n\nexport class WidgetsRouter implements RouterMount {\n constructor(\n private dashboardId: string,\n private dashboard: Dashboard,\n private connectors: ConfiguredConnector[],\n private storage: ServerStorage,\n ) {}\n\n private resolve(\n id: string,\n widget: Widget,\n ): Promise<CachedWidget | undefined> {\n return resolveWidget(id, widget, this.connectors, this.storage);\n }\n\n mount(app: Hono): void {\n const base = `/dashboards/${this.dashboardId}/widgets`;\n\n app.get(base, async (c) => {\n const entries = Object.entries(this.dashboard.widgets);\n const resolved = await Promise.all(\n entries.map(([key, widget]) => this.resolve(key, widget)),\n );\n const widgets = resolved.filter(\n (w): w is CachedWidget => w !== undefined,\n );\n const response: WidgetsListResponse = { widgets };\n return c.json(response);\n });\n\n app.get(`${base}/:widgetId`, async (c) => {\n const widgetId = c.req.param('widgetId');\n const widget = this.dashboard.widgets[widgetId];\n if (!widget) {\n return c.json({ error: 'Widget not found' }, 404);\n }\n const result = await this.resolve(widgetId, widget);\n if (!result) {\n return c.json({ error: 'Widget not found' }, 404);\n }\n return c.json(result);\n });\n }\n}\n","export { InMemoryStorage } from '@rawdash/core';\n","import type { DashboardConfig } from '@rawdash/core';\n\nimport type { RouterMount } from './router';\nimport { HealthRouter } from './routers/health';\nimport { RetentionRouter } from './routers/retention';\nimport { SyncRouter } from './routers/sync';\nimport { WidgetsRouter } from './routers/widgets';\nimport { InMemoryStorage } from './storage';\nimport type { ServerStorage } from './types';\n\nexport function createEngineRouters(\n config: DashboardConfig,\n storage: ServerStorage = new InMemoryStorage(),\n): RouterMount[] {\n const widgetRouters = Object.entries(config.dashboards).map(\n ([dashboardId, dashboard]) =>\n new WidgetsRouter(dashboardId, dashboard, config.connectors, storage),\n );\n\n return [\n ...widgetRouters,\n new SyncRouter(config, storage),\n new RetentionRouter(config, storage),\n new HealthRouter(storage),\n ];\n}\n","import { Hono } from 'hono';\n\nimport type { RouterMount } from './router';\n\nexport function createServer(routers: RouterMount[]): Hono {\n const app = new Hono();\n for (const router of routers) {\n router.mount(app);\n }\n return app;\n}\n","import type {\n CachedWidget,\n DashboardConfig,\n SyncState,\n TriggerSyncResponse,\n} from '@rawdash/core';\nimport { InMemoryStorage, resolveWidget } from '@rawdash/core';\n\nimport { SyncRouter } from './routers/sync';\nimport type { ServerStorage } from './types';\n\nexport interface EngineOptions {\n storage?: ServerStorage;\n}\n\nexport interface Engine {\n getWidget(\n dashboardId: string,\n widgetId: string,\n ): Promise<CachedWidget | undefined>;\n getWidgets(dashboardId: string): Promise<CachedWidget[]>;\n getHealth(): Promise<SyncState>;\n triggerSync(): Promise<TriggerSyncResponse>;\n}\n\nexport function createEngine(\n config: DashboardConfig,\n options: EngineOptions = {},\n): Engine {\n const storage: ServerStorage = options.storage ?? new InMemoryStorage();\n const syncRouter = new SyncRouter(config, storage);\n\n return {\n async getWidget(dashboardId, widgetId) {\n const dashboard = config.dashboards[dashboardId];\n if (!dashboard) {\n return undefined;\n }\n const widget = dashboard.widgets[widgetId];\n if (!widget) {\n return undefined;\n }\n return resolveWidget(widgetId, widget, config.connectors, storage);\n },\n\n async getWidgets(dashboardId) {\n const dashboard = config.dashboards[dashboardId];\n if (!dashboard) {\n return [];\n }\n const entries = Object.entries(dashboard.widgets);\n const resolved = await Promise.all(\n entries.map(([key, widget]) =>\n resolveWidget(key, widget, config.connectors, storage),\n ),\n );\n return resolved.filter((w): w is CachedWidget => w !== undefined);\n },\n\n async getHealth() {\n return storage.getSyncState();\n },\n\n async triggerSync() {\n const state = await storage.getSyncState();\n if (state.status === 'syncing') {\n return { triggered: false };\n }\n void syncRouter.runSync().catch((error) => {\n console.error('Rawdash sync failed', error);\n });\n return { triggered: true };\n },\n };\n}\n","export { computeMetric } from '@rawdash/core';\n"],"mappings":"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","names":["InMemoryStorage","resolveWidget","InMemoryStorage","resolveWidget"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rawdash/server",
3
- "version": "0.10.1",
3
+ "version": "0.11.0",
4
4
  "description": "Rawdash standalone Hono server",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -24,7 +24,7 @@
24
24
  "dependencies": {
25
25
  "@hono/node-server": "^1.13.7",
26
26
  "hono": "^4.7.7",
27
- "@rawdash/core": "0.10.1"
27
+ "@rawdash/core": "0.11.0"
28
28
  },
29
29
  "devDependencies": {
30
30
  "tsup": "^8.0.0",