@synapse-sdk/client 0.3.3 → 0.3.6

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/tasks.js CHANGED
@@ -7,9 +7,10 @@
7
7
  // unchanged part keeps its object.
8
8
  import { SynapseError } from "@synapse-sdk/core";
9
9
  import { replaceEqualDeep } from "./util.js";
10
+ import { ulid } from "./scene.js";
10
11
  /** The namespaces the facet reads and writes (the runtime's names). */
11
12
  export const TASKS_NAMESPACES = { declarations: "tasks", status: "task_status", catalog: "task_catalog" };
12
- /** What `status.value` is before the runtime said anything: neither scope's state known, no tasks. */
13
+ /** What `status.get()` is before the runtime said anything: neither scope's state known, no tasks. */
13
14
  export const EMPTY_TASKS_STATUS = { robot: { state: undefined, tasks: {} }, project: { state: undefined, tasks: {} } };
14
15
  const isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
15
16
  /** A run row (`robot` / `project`: `{state, since, reason?}`) as the scope's run fields. */
@@ -49,7 +50,7 @@ export function tasksStatusOf(rows, unplaced = () => { }) {
49
50
  return { robot: { ...runOf(rows.robot), tasks: robot }, project: { ...runOf(rows.project), tasks: project } };
50
51
  }
51
52
  /**
52
- * A read-only handle over one namespace of the node: `value` is `derive` of the mirror, recomputed only
53
+ * A read-only handle over one namespace of the node: `get()` is `derive` of the mirror, recomputed only
53
54
  * when the mirror changed and shared structurally with the previous value. The namespace is opened on
54
55
  * the first touch of any member.
55
56
  */
@@ -65,8 +66,8 @@ class DerivedHandle {
65
66
  this.#value = empty;
66
67
  }
67
68
  #handle() { return (this.#h ??= this.open()); }
68
- get value() {
69
- const rows = this.#handle().value;
69
+ get() {
70
+ const rows = this.#handle().get();
70
71
  if (rows !== this.#from) {
71
72
  this.#from = rows;
72
73
  this.#value = replaceEqualDeep(this.#value, this.derive(rows));
@@ -77,9 +78,9 @@ class DerivedHandle {
77
78
  ready() { return this.#handle().ready(); }
78
79
  async *watch() {
79
80
  for await (const _ of this.#handle().watch())
80
- yield this.value;
81
+ yield this.get();
81
82
  }
82
- subscribe(listener) { return this.#handle().subscribe(listener); }
83
+ onChange(cb) { return this.#handle().onChange(() => cb(this.get())); }
83
84
  }
84
85
  /** The robot's declarations: the node's handle on `tasks`; every write waits for the value to be current first. */
85
86
  class Declarations {
@@ -89,20 +90,33 @@ class Declarations {
89
90
  this.open = open;
90
91
  }
91
92
  #handle() { return (this.#h ??= this.open()); }
92
- get value() { return this.#handle().value; }
93
- get(instance) { return this.#handle().get(instance); }
93
+ get(instance) {
94
+ const h = this.#handle();
95
+ return (instance === undefined ? h.get() : h.get(instance));
96
+ }
94
97
  get synced() { return this.#handle().synced; }
95
98
  get status() { return this.#handle().status; }
99
+ changed() { return this.#handle().changed(); }
96
100
  ready() { return this.#handle().ready(); }
97
101
  async set(a, b) {
98
102
  const h = this.#handle();
99
103
  await h.ready();
100
- await (typeof a === "string" ? h.set(a, b) : h.set(a));
104
+ if (typeof a === "string") {
105
+ await h.set(a, b);
106
+ return;
107
+ }
108
+ // One object: a declaration (its `ref` is a string) gets a minted instance; else it is a map of declarations.
109
+ if (typeof a.ref === "string") {
110
+ const instance = ulid();
111
+ await h.set(instance, a);
112
+ return instance;
113
+ }
114
+ await h.set(a);
101
115
  }
102
116
  async delete(instance) { const h = this.#handle(); await h.ready(); await h.delete(instance); }
103
117
  async clear() { const h = this.#handle(); await h.ready(); await h.clear(); }
104
118
  watch(instance) { return this.#handle().watch(instance); }
105
- subscribe(listener) { return this.#handle().subscribe(listener); }
119
+ onChange(cb) { return this.#handle().onChange(cb); }
106
120
  }
107
121
  /** `node.tasks`. `attach(name)` hands out the node's handle on a namespace; `call` starts a call on the current session. */
108
122
  export class TasksFacet {
package/dist/topics.d.ts CHANGED
@@ -147,5 +147,7 @@ export declare class TopicSubscription<T> implements Subscription<T> {
147
147
  /** Ends the subscription: the follow task stops, every track is closed, a pending `next()` returns `undefined`. */
148
148
  unsubscribe(): void;
149
149
  [Symbol.asyncDispose](): Promise<void>;
150
+ /** The callback form's read loop (`node.subscribe(topic, cb)`): `cb` with each batch `next()` returns, until the subscription ends; a throwing `cb` is rethrown later and the loop goes on. */
151
+ deliverTo(cb: (batch: Envelope<T>[]) => void): void;
150
152
  }
151
153
  export {};
package/dist/topics.js CHANGED
@@ -16,7 +16,7 @@ import { FLAGS, MSGPACK, SynapseError, TYPES, auParamSets, auSyncPoints, decode
16
16
  import { Handle, start as startHandle } from "./channel.js";
17
17
  import { FecReader, FecWriter, ReportWriter, feedbackListener, requireFec } from "./fec.js";
18
18
  import { RETAINED_FRAME_MAX_AGE_MS, StreamWriter, latestSubscription, moqTimestamp, streamTopicSubscription, waitActive, writeLatest } from "./session.js";
19
- import { AsyncQueue, deferred, withTimeout, TIMEOUT } from "./util.js";
19
+ import { AsyncQueue, deferred, rethrowLater, withTimeout, TIMEOUT } from "./util.js";
20
20
  /** moq's cap on one `stream` frame (a group's cache). */
21
21
  const STREAM_FRAME_MAX = 32 * 1024 * 1024;
22
22
  /** The bound on adding one publisher (its broadcast, its `desc`, its `data` subscription). */
@@ -627,6 +627,22 @@ export class TopicSubscription {
627
627
  this.#signal();
628
628
  }
629
629
  async [Symbol.asyncDispose]() { this.unsubscribe(); }
630
+ /** The callback form's read loop (`node.subscribe(topic, cb)`): `cb` with each batch `next()` returns, until the subscription ends; a throwing `cb` is rethrown later and the loop goes on. */
631
+ deliverTo(cb) {
632
+ void (async () => {
633
+ for (;;) {
634
+ const b = await this.next();
635
+ if (!b)
636
+ return;
637
+ try {
638
+ cb(b);
639
+ }
640
+ catch (e) {
641
+ rethrowLater(e);
642
+ }
643
+ }
644
+ })();
645
+ }
630
646
  }
631
647
  /** A source is done: its subscription and its request are closed (its pending read settles as the end). */
632
648
  function closeSource(src) {