svelte-realtime 0.1.7 → 0.1.8

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
@@ -1025,6 +1025,21 @@ export const stats = live.stream('stats', async (ctx) => {
1025
1025
  }, { merge: 'set' });
1026
1026
  ```
1027
1027
 
1028
+ The function receives a `ctx` object with `publish`, `throttle`, `debounce`, and `signal` -- the same helpers available in RPC handlers (minus `user` and `ws`, since cron runs outside a connection). Use `ctx.publish` for fine-grained control, e.g. publishing individual `created`/`deleted` events on a crud stream:
1029
+
1030
+ ```js
1031
+ export const cleanup = live.cron('0 * * * *', 'boards', async (ctx) => {
1032
+ const stale = await listStaleBoards();
1033
+ for (const board of stale) {
1034
+ await deleteBoard(board.board_id);
1035
+ ctx.publish('boards', 'deleted', { board_id: board.board_id });
1036
+ }
1037
+ // returning undefined skips the automatic 'set' publish
1038
+ });
1039
+ ```
1040
+
1041
+ If the function returns a value, it is published as a `set` event (same as before). If it returns `undefined`, no automatic publish happens -- this lets you use `ctx.publish` exclusively without an unwanted `set` event overwriting your crud updates.
1042
+
1028
1043
  Cron expressions use 5 fields: `minute hour day month weekday`. Supported syntax: `*`, single values, ranges (`9-17`), lists (`0,15,30`), and steps (`*/5`).
1029
1044
 
1030
1045
  The platform is captured automatically from the first RPC call. If your app starts cron jobs before any WebSocket connections, call `setCronPlatform(platform)` in your `open` hook.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-realtime",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Realtime RPC and reactive subscriptions for SvelteKit, built on svelte-adapter-uws",
5
5
  "author": "Kevin Radziszewski",
6
6
  "license": "MIT",
package/server.d.ts CHANGED
@@ -1,5 +1,22 @@
1
1
  import type { Platform, WebSocket } from 'svelte-adapter-uws';
2
2
 
3
+ /**
4
+ * Context passed to `live.cron()` functions.
5
+ * No `user` or `ws` since cron jobs run outside a connection.
6
+ */
7
+ export interface CronContext {
8
+ /** The platform API (publish, send, topic helpers). */
9
+ platform: Platform;
10
+ /** Shorthand for `platform.publish` -- delegates to whatever platform was passed in. */
11
+ publish: Platform['publish'];
12
+ /** Throttled publish -- sends at most once per `ms` milliseconds. */
13
+ throttle(topic: string, event: string, data: any, ms: number): void;
14
+ /** Debounced publish -- sends after `ms` milliseconds of silence. */
15
+ debounce(topic: string, event: string, data: any, ms: number): void;
16
+ /** Send a point-to-point signal to a specific user. */
17
+ signal(userId: string, event: string, data: any): void;
18
+ }
19
+
3
20
  /**
4
21
  * Context passed to every `live()` and `live.stream()` function.
5
22
  */
@@ -372,18 +389,32 @@ export namespace live {
372
389
  /**
373
390
  * Create a server-side scheduled function that publishes to a topic on a cron schedule.
374
391
  *
392
+ * The function receives a `ctx` object with `publish`, `throttle`, `debounce`, and `signal`.
393
+ * If the function returns a value, it is published as a `set` event on the topic.
394
+ * If the function returns `undefined`, no automatic publish happens (use `ctx.publish` instead).
395
+ *
375
396
  * @param schedule - Cron expression (5 fields: minute hour day month weekday)
376
397
  * @param topic - Topic to publish results to
377
398
  * @param fn - Async function to run on schedule
378
399
  *
379
400
  * @example
380
401
  * ```js
402
+ * // Return a value -- published as 'set' automatically
381
403
  * export const refreshStats = live.cron('*\/5 * * * *', 'stats', async () => {
382
404
  * return db.stats();
383
405
  * });
406
+ *
407
+ * // Use ctx.publish for fine-grained control (e.g. crud streams)
408
+ * export const cleanup = live.cron('0 * * * *', 'boards', async (ctx) => {
409
+ * const stale = await listStaleBoards();
410
+ * for (const board of stale) {
411
+ * await deleteBoard(board.board_id);
412
+ * ctx.publish('boards', 'deleted', { board_id: board.board_id });
413
+ * }
414
+ * });
384
415
  * ```
385
416
  */
386
- function cron<T extends () => any>(
417
+ function cron<T extends ((ctx: CronContext) => any) | (() => any)>(
387
418
  schedule: string,
388
419
  topic: string,
389
420
  fn: T
@@ -773,6 +804,11 @@ export function _activateDerived(platform: Platform): void;
773
804
  */
774
805
  export function _clearCron(): void;
775
806
 
807
+ /**
808
+ * Run all matching cron jobs for the current minute. Exported for testing.
809
+ */
810
+ export function _tickCron(): Promise<void>;
811
+
776
812
  /**
777
813
  * Set a global error handler for cron job failures.
778
814
  * Without this, cron errors are logged in dev and silently swallowed in production.
package/server.js CHANGED
@@ -1270,7 +1270,7 @@ export function _restoreHmr(snap) {
1270
1270
  }
1271
1271
  }
1272
1272
 
1273
- async function _tickCron() {
1273
+ export async function _tickCron() {
1274
1274
  if (_lazyQueue.length) await _resolveAllLazy();
1275
1275
  const now = new Date();
1276
1276
  const minute = now.getMinutes();
@@ -1296,8 +1296,18 @@ async function _tickCron() {
1296
1296
  }
1297
1297
  return;
1298
1298
  }
1299
- const result = await entry.fn();
1300
- _cronPlatform.publish(entry.topic, 'set', result);
1299
+ const _h = _getCtxHelpers(_cronPlatform);
1300
+ const ctx = {
1301
+ platform: _cronPlatform,
1302
+ publish: _h.publish,
1303
+ throttle: _h.throttle,
1304
+ debounce: _h.debounce,
1305
+ signal: _h.signal
1306
+ };
1307
+ const result = await entry.fn(ctx);
1308
+ if (result !== undefined) {
1309
+ _cronPlatform.publish(entry.topic, 'set', result);
1310
+ }
1301
1311
  } catch (err) {
1302
1312
  if (_cronErrorHandler) {
1303
1313
  _cronErrorHandler(path, err);