@filamind-app/core 0.1.2 → 0.1.3

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
@@ -18,6 +18,7 @@ The shared foundation of the FilaMind suite — **framework-agnostic TypeScript*
18
18
  | `moonraker/client.ts` | `MoonrakerClient` — reconnecting JSON-RPC WS (**injectable socket**, backoff **+ jitter + max-attempts**), id-correlated, notify fan-out, re-subscribe on reconnect, **REST file channel** (`upload`/`download`) |
19
19
  | `moonraker/discovery.ts` | **zero-config endpoint discovery** — `resolveMoonrakerUrl()` races candidate endpoints (same-origin proxy / direct `:7125` / localhost) → first to open wins; runtime `override` short-circuits. Socket-injectable |
20
20
  | `moonraker/subscriptions.ts` | the **versioned** canonical subscription contract — `NARROW_STATUS` / `FULL_CONTROL` tiers + `tier()` |
21
+ | `moonraker/rpc-types.ts` | **RPC type safety** — `RpcError` (keeps JSON-RPC `code`/`data`) · `MoonrakerMethods` typed-`call` result map · `NotifyEvent` + `parseNotifyEvent()` discriminated notify union |
21
22
  | `printer/klippy.ts` | the Klippy lifecycle (`ready`/`startup`/`shutdown`/`error`/`disconnected`) — tracked apart from the socket so a FIRMWARE_RESTART re-seeds instead of showing stale-as-live |
22
23
  | `printer/prompt-parser.ts` | parses Klipper's `// action:prompt_*` protocol into structured modal dialogs (`PromptParser`) |
23
24
  | `session/session.ts` | **`FilaMindSession`** — the orchestrator: staged init (identify → capabilities → query/seed → subscribe), routes `notify_*`, owns the Klippy-aware `live`/stale gate |
package/dist/index.d.ts CHANGED
@@ -90,6 +90,85 @@ declare class Logger {
90
90
  /** A no-op logger for when none is supplied. */
91
91
  declare const NULL_LOGGER: Logger;
92
92
 
93
+ /** A JSON-RPC error that keeps Moonraker's numeric `code` and optional `data` payload. */
94
+ declare class RpcError extends Error {
95
+ readonly code?: number | undefined;
96
+ readonly data?: unknown | undefined;
97
+ constructor(message: string, code?: number | undefined, data?: unknown | undefined);
98
+ }
99
+ interface ServerInfo {
100
+ klippy_connected: boolean;
101
+ klippy_state: 'ready' | 'startup' | 'shutdown' | 'error' | 'disconnected';
102
+ components?: string[];
103
+ warnings?: string[];
104
+ [k: string]: unknown;
105
+ }
106
+ interface PrinterInfo {
107
+ state: 'ready' | 'startup' | 'shutdown' | 'error';
108
+ state_message: string;
109
+ hostname?: string;
110
+ software_version?: string;
111
+ [k: string]: unknown;
112
+ }
113
+ interface QueryResult {
114
+ eventtime: number;
115
+ status: Record<string, unknown>;
116
+ }
117
+ /** Result types for the methods the suite calls most. Unlisted methods still work via `call<T>()`. */
118
+ interface MoonrakerMethods {
119
+ 'server.info': ServerInfo;
120
+ 'server.connection.identify': {
121
+ connection_id: number;
122
+ };
123
+ 'printer.info': PrinterInfo;
124
+ 'printer.objects.list': {
125
+ objects: string[];
126
+ };
127
+ 'printer.objects.query': QueryResult;
128
+ 'printer.objects.subscribe': QueryResult;
129
+ 'printer.gcode.script': 'ok';
130
+ 'printer.emergency_stop': 'ok';
131
+ 'printer.restart': 'ok';
132
+ 'printer.firmware_restart': 'ok';
133
+ 'machine.system_info': {
134
+ system_info: Record<string, unknown>;
135
+ };
136
+ 'machine.reboot': 'ok';
137
+ 'machine.shutdown': 'ok';
138
+ 'server.database.get_item': {
139
+ namespace: string;
140
+ key?: string;
141
+ value: unknown;
142
+ };
143
+ 'server.database.post_item': {
144
+ namespace: string;
145
+ key?: string;
146
+ value: unknown;
147
+ };
148
+ }
149
+ /** A narrowed view of Moonraker's `notify_*` broadcasts (whose raw params are positional arrays). */
150
+ type NotifyEvent = {
151
+ method: 'notify_status_update';
152
+ status: Record<string, unknown>;
153
+ eventtime: number;
154
+ } | {
155
+ method: 'notify_gcode_response';
156
+ response: string;
157
+ } | {
158
+ method: 'notify_klippy_ready';
159
+ } | {
160
+ method: 'notify_klippy_shutdown';
161
+ } | {
162
+ method: 'notify_klippy_disconnected';
163
+ } | {
164
+ method: 'notify_agent_event';
165
+ agent: string;
166
+ event: string;
167
+ data: unknown;
168
+ };
169
+ /** Parse a raw (method, params) notify into a typed event, or null for an unhandled method. */
170
+ declare function parseNotifyEvent(method: string, params: unknown): NotifyEvent | null;
171
+
93
172
  /** Minimal WebSocket surface the client uses — the DOM WebSocket satisfies it; tests fake it. */
94
173
  interface WebSocketLike {
95
174
  send(data: string): void;
@@ -130,6 +209,7 @@ declare class MoonrakerClient implements Connector {
130
209
  setCallbacks(cb: ConnectorCallbacks): void;
131
210
  connect(): Promise<void>;
132
211
  close(): void;
212
+ call<M extends keyof MoonrakerMethods>(method: M, params?: Record<string, unknown>): Promise<MoonrakerMethods[M]>;
133
213
  call<T = unknown>(method: string, params?: Record<string, unknown>): Promise<T>;
134
214
  subscribe(objects: SubscriptionMap): Promise<void>;
135
215
  upload(root: string, file: File, onProgress?: (pct: number) => void): Promise<void>;
@@ -543,4 +623,4 @@ declare function applySettings(s: UserSettings, el?: {
543
623
  dir: 'ltr' | 'rtl';
544
624
  };
545
625
 
546
- export { type AgentAllow, type AgentEvent, type BackendMessage, type Catalog, CommandSender, type CommandSenderOptions, type ConnectionState, type Connector, type ConnectorCallbacks, DEFAULT_LOCALE, DEFAULT_SETTINGS, DEFAULT_THEME, type DiscoveryOptions, FILAMIND_COMMAND_EVENT, FULL_CONTROL, FilaMindSession, type IdentifyInfo, type KlippyState, LOCALES, type Listener, type LocaleMeta, type LocationLike, type LogEntry, type LogLevel, Logger, MoonrakerClient, type MoonrakerClientOptions, NARROW_STATUS, NULL_LOGGER, Observable, type Params, type PluralCategory, type PrinterObjects, PrinterState, type PromptButton, type PromptDialog, type PromptEvent, PromptParser, REMOTE_MESSAGE_LEVELS, REMOTE_VIEWS, RTL_LOCALES, type RemoteCommand, type RemoteMessageLevel, type RemoteView, type RestorePoint, RestorePoints, type RestoreStore, SETTINGS_VERSION, SUBSCRIPTION_CONTRACT_VERSION, type SessionOptions, type SettingsPersistence, SettingsStore, type Source, type Stamped, type SubscriptionMap, type SubscriptionTier, type SurfaceTarget, type ThemeName, type ThemeTokens, Translator, UNKNOWN, type UserSettings, type WebSocketLike, type WidgetDefinition, WriteArbiter, type WriteGuard, WriteRefused, _resetRegistry, aggregateSubscriptions, applySettings, applyTheme, deepMerge, deriveCandidates, deriveKlippyState, deriveMachineId, fnv1a, freshness, getWidget, getWidgets, handleAgentCommand, isKlippyLive, isRtl, isStale, localStoragePersistence, localeMeta, memoryPersistence, memoryRestoreStore, mergeSubscriptions, migrate, moonrakerDbPersistence, parseAgentEvent, parseCommand, pluralCategory, registerWidget, resolveMessage, resolveMoonrakerUrl, roamSettings, stamp, themeToCssVars, themes, tier, translate };
626
+ export { type AgentAllow, type AgentEvent, type BackendMessage, type Catalog, CommandSender, type CommandSenderOptions, type ConnectionState, type Connector, type ConnectorCallbacks, DEFAULT_LOCALE, DEFAULT_SETTINGS, DEFAULT_THEME, type DiscoveryOptions, FILAMIND_COMMAND_EVENT, FULL_CONTROL, FilaMindSession, type IdentifyInfo, type KlippyState, LOCALES, type Listener, type LocaleMeta, type LocationLike, type LogEntry, type LogLevel, Logger, MoonrakerClient, type MoonrakerClientOptions, type MoonrakerMethods, NARROW_STATUS, NULL_LOGGER, type NotifyEvent, Observable, type Params, type PluralCategory, type PrinterInfo, type PrinterObjects, PrinterState, type PromptButton, type PromptDialog, type PromptEvent, PromptParser, type QueryResult, REMOTE_MESSAGE_LEVELS, REMOTE_VIEWS, RTL_LOCALES, type RemoteCommand, type RemoteMessageLevel, type RemoteView, type RestorePoint, RestorePoints, type RestoreStore, RpcError, SETTINGS_VERSION, SUBSCRIPTION_CONTRACT_VERSION, type ServerInfo, type SessionOptions, type SettingsPersistence, SettingsStore, type Source, type Stamped, type SubscriptionMap, type SubscriptionTier, type SurfaceTarget, type ThemeName, type ThemeTokens, Translator, UNKNOWN, type UserSettings, type WebSocketLike, type WidgetDefinition, WriteArbiter, type WriteGuard, WriteRefused, _resetRegistry, aggregateSubscriptions, applySettings, applyTheme, deepMerge, deriveCandidates, deriveKlippyState, deriveMachineId, fnv1a, freshness, getWidget, getWidgets, handleAgentCommand, isKlippyLive, isRtl, isStale, localStoragePersistence, localeMeta, memoryPersistence, memoryRestoreStore, mergeSubscriptions, migrate, moonrakerDbPersistence, parseAgentEvent, parseCommand, parseNotifyEvent, pluralCategory, registerWidget, resolveMessage, resolveMoonrakerUrl, roamSettings, stamp, themeToCssVars, themes, tier, translate };
package/dist/index.js CHANGED
@@ -105,6 +105,51 @@ function deepMerge(target, patch) {
105
105
  return out;
106
106
  }
107
107
 
108
+ // src/moonraker/rpc-types.ts
109
+ var RpcError = class extends Error {
110
+ constructor(message, code, data) {
111
+ super(message);
112
+ this.code = code;
113
+ this.data = data;
114
+ this.name = "RpcError";
115
+ }
116
+ code;
117
+ data;
118
+ };
119
+ function parseNotifyEvent(method, params) {
120
+ const arr = Array.isArray(params) ? params : [];
121
+ switch (method) {
122
+ case "notify_status_update":
123
+ return {
124
+ method: "notify_status_update",
125
+ status: arr[0] ?? {},
126
+ eventtime: typeof arr[1] === "number" ? arr[1] : 0
127
+ };
128
+ case "notify_gcode_response":
129
+ return {
130
+ method: "notify_gcode_response",
131
+ response: typeof arr[0] === "string" ? arr[0] : ""
132
+ };
133
+ case "notify_klippy_ready":
134
+ return { method: "notify_klippy_ready" };
135
+ case "notify_klippy_shutdown":
136
+ return { method: "notify_klippy_shutdown" };
137
+ case "notify_klippy_disconnected":
138
+ return { method: "notify_klippy_disconnected" };
139
+ case "notify_agent_event": {
140
+ const e = arr[0] ?? {};
141
+ return {
142
+ method: "notify_agent_event",
143
+ agent: typeof e.agent === "string" ? e.agent : "",
144
+ event: typeof e.event === "string" ? e.event : "",
145
+ data: e.data
146
+ };
147
+ }
148
+ default:
149
+ return null;
150
+ }
151
+ }
152
+
108
153
  // src/moonraker/client.ts
109
154
  var defaultWsFactory = (url) => new WebSocket(url);
110
155
  var MoonrakerClient = class {
@@ -169,7 +214,7 @@ var MoonrakerClient = class {
169
214
  return new Promise((resolve, reject) => {
170
215
  const timer = setTimeout(() => {
171
216
  this.pending.delete(id);
172
- reject(new Error(`moonraker request timed out: ${method}`));
217
+ reject(new RpcError(`moonraker request timed out: ${method}`));
173
218
  }, this.opts.requestTimeoutMs ?? 1e4);
174
219
  this.pending.set(id, { resolve, reject, timer });
175
220
  this.send({ jsonrpc: "2.0", method, params, id });
@@ -246,7 +291,7 @@ var MoonrakerClient = class {
246
291
  if (!p) return;
247
292
  clearTimeout(p.timer);
248
293
  this.pending.delete(msg.id);
249
- if (msg.error) p.reject(new Error(msg.error.message ?? "rpc error"));
294
+ if (msg.error) p.reject(new RpcError(msg.error.message ?? "rpc error", msg.error.code, msg.error.data));
250
295
  else p.resolve(msg.result);
251
296
  return;
252
297
  }
@@ -1239,6 +1284,7 @@ export {
1239
1284
  REMOTE_VIEWS,
1240
1285
  RTL_LOCALES,
1241
1286
  RestorePoints,
1287
+ RpcError,
1242
1288
  SETTINGS_VERSION,
1243
1289
  SUBSCRIPTION_CONTRACT_VERSION,
1244
1290
  SettingsStore,
@@ -1271,6 +1317,7 @@ export {
1271
1317
  moonrakerDbPersistence,
1272
1318
  parseAgentEvent,
1273
1319
  parseCommand,
1320
+ parseNotifyEvent,
1274
1321
  pluralCategory,
1275
1322
  registerWidget,
1276
1323
  resolveMessage,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@filamind-app/core",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Shared foundation for the FilaMind suite — Moonraker client, reactive printer state, provenance-stamped values, design tokens, and the widget/plugin registry. Framework-agnostic TypeScript.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "repository": {