@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/calls.d.ts +12 -6
- package/dist/calls.js +35 -18
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/node.d.ts +62 -24
- package/dist/node.js +205 -66
- package/dist/scene.d.ts +166 -61
- package/dist/scene.js +1254 -343
- package/dist/scene_frames.d.ts +2 -2
- package/dist/scene_frames.js +1 -1
- package/dist/session.d.ts +3 -1
- package/dist/session.js +5 -3
- package/dist/store.d.ts +33 -14
- package/dist/store.js +209 -93
- package/dist/synapse.d.ts +73 -49
- package/dist/synapse.js +180 -116
- package/dist/tasks.d.ts +1 -1
- package/dist/tasks.js +24 -10
- package/dist/topics.d.ts +2 -0
- package/dist/topics.js +17 -1
- package/dist/types.d.ts +292 -110
- package/dist/util.d.ts +43 -0
- package/dist/util.js +97 -1
- package/dist/view.d.ts +5 -3
- package/dist/view.js +21 -10
- package/package.json +2 -2
package/dist/scene.d.ts
CHANGED
|
@@ -3,13 +3,15 @@ import { SynapseError, type ErrorBody, type ProjectSnapshot } from "@synapse-sdk
|
|
|
3
3
|
import type { Node } from "./node.ts";
|
|
4
4
|
import { StreamWriter, type Session } from "./session.ts";
|
|
5
5
|
import type { Warn } from "./topics.ts";
|
|
6
|
-
import type {
|
|
7
|
-
import { AsyncQueue, type Deferred } from "./util.ts";
|
|
6
|
+
import type { LiveJoints, LivePose, LiveRemoved, LiveState, Quat, SceneAuthored, SceneDiffOp, SceneEntity, SceneEntityLive, SceneEntityRef, SceneEntityView, SceneHandle, SceneKind, SceneLive, SceneOp, ScenePlace, SceneSpawnOptions, SceneState, SceneStatus, SceneTree, SceneTxn, SceneView, Vec3 } from "./types.ts";
|
|
7
|
+
import { AsyncQueue, type Deferred, type StateValue } from "./util.ts";
|
|
8
8
|
/** How many batches a feed may fall behind before it is ended (the store's `STORE_FEED_CAP`). */
|
|
9
9
|
export declare const SCENE_FEED_CAP = 256;
|
|
10
10
|
/** Keys a `patch` may not set (the runtime refuses them); a txn never folds such a patch into a spawn. */
|
|
11
11
|
export declare const PATCH_PROTECTED: readonly string[];
|
|
12
12
|
type Entities = Map<string, SceneEntity>;
|
|
13
|
+
/** An entity named by its id or by a view of it (the id the view names now). */
|
|
14
|
+
type EntityArg = string | SceneEntityView;
|
|
13
15
|
/**
|
|
14
16
|
* A fresh entity id: a ULID (26 Crockford base-32 characters) made from a UUIDv7 (48-bit ms, version,
|
|
15
17
|
* 74 random bits, variant), so ids sort by the time they were minted; within one millisecond the
|
|
@@ -37,19 +39,19 @@ export declare function treeOf(entities: Readonly<Record<string, SceneEntity>>):
|
|
|
37
39
|
export declare class Txn implements SceneTxn {
|
|
38
40
|
#private;
|
|
39
41
|
get ops(): readonly SceneOp[];
|
|
40
|
-
/** Spawns an entity of `kind` under `opts.parent` (default the world root) with the components given (`layer` `authored` when not given); its id is minted here (or `opts.id`, a known one) and returned. No `order` is sent: the runtime appends it after its siblings. */
|
|
41
|
-
spawn(kind:
|
|
42
|
-
/** Sets components of
|
|
43
|
-
patch(
|
|
44
|
-
rename(
|
|
45
|
-
/** Moves
|
|
46
|
-
reparent(
|
|
47
|
-
/** Despawns
|
|
48
|
-
despawn(
|
|
42
|
+
/** Spawns an entity of `kind` under `opts.parent` (default the world root) with the components given (`layer` `authored` when not given, else `calibration`; a live entity is not spawned here, it comes from `scene.live.upsert`); its id is minted here (or `opts.id`, a known one) and returned. No `order` is sent: the runtime appends it after its siblings. */
|
|
43
|
+
spawn(kind: SceneKind, opts: SceneSpawnOptions): string;
|
|
44
|
+
/** Sets components of the entity (one level deep: an object merges into an object). */
|
|
45
|
+
patch(entity: EntityArg, set: Partial<SceneEntity>): void;
|
|
46
|
+
rename(entity: EntityArg, name: string): void;
|
|
47
|
+
/** Moves the entity under `parent` (`null`: the world root), before or after a sibling (default: after the last). */
|
|
48
|
+
reparent(entity: EntityArg, parent: EntityArg | null, place?: ScenePlace): void;
|
|
49
|
+
/** Despawns the entity (`cascade`: with its subtree). One spawned in this batch is cancelled instead, unless it has children spawned in the batch and `cascade` is off (then the runtime decides). */
|
|
50
|
+
despawn(entity: EntityArg, opts?: {
|
|
49
51
|
cascade?: boolean;
|
|
50
52
|
}): void;
|
|
51
|
-
/** Locks or unlocks
|
|
52
|
-
setLocked(
|
|
53
|
+
/** Locks or unlocks the entity (a flags-only patch, which a lock lets through). */
|
|
54
|
+
setLocked(entity: EntityArg, locked: boolean): void;
|
|
53
55
|
}
|
|
54
56
|
/**
|
|
55
57
|
* Applies one diff op of a batch the runtime stamped `t` by `by` to the authored entities (the
|
|
@@ -57,8 +59,6 @@ export declare class Txn implements SceneTxn {
|
|
|
57
59
|
* `meta` is `{rev, t, by}`, as the runtime stamped it.
|
|
58
60
|
*/
|
|
59
61
|
export declare function foldAuthored(authored: Entities, op: SceneDiffOp, t: number, by: string | null): string[];
|
|
60
|
-
/** What changed from `old` to `next`, in the diff ops' shapes (a snapshot replacing the mirror, the mirror emptying): a spawn per new entity, a despawn per gone one, and per changed one a reparent (parent or order), a rename (name) and a patch of the other keys that differ. */
|
|
61
|
-
export declare function netDifference(old: Entities, next: Entities): SceneDiffOp[];
|
|
62
62
|
/** One live row as this node keeps it: the whole live entity of an upsert (absent: an override of an authored entity), the lanes, and the newest lane stamp (the runtime's clock). */
|
|
63
63
|
export interface LiveRow {
|
|
64
64
|
entity?: SceneEntity;
|
|
@@ -85,6 +85,10 @@ export interface LiveFrame {
|
|
|
85
85
|
}
|
|
86
86
|
/** A keyframe as a fresh live table. */
|
|
87
87
|
export declare function liveTableOf(k: LiveFrame): LiveTable;
|
|
88
|
+
/** The authored or calibration entity named `name` (live overrides never count). */
|
|
89
|
+
export declare function authoredNamed(authored: Entities, name: string): SceneEntity | undefined;
|
|
90
|
+
/** The id of the live entity named `name` (a lane-only row carries no name). */
|
|
91
|
+
export declare function liveNamed(live: LiveTable, name: string): string | undefined;
|
|
88
92
|
/** One tick folded into `table` with the runtime's rules (an upsert replaces the whole row, a lane replaces its lane, a remove drops the row); returns the ids it touched. */
|
|
89
93
|
export declare function foldLive(table: LiveTable, d: LiveFrame): string[];
|
|
90
94
|
/** The merged read of one entity: the pose lane replaces `xform.t`/`xform.q` (the rest of the xform stays), the joints lane replaces `joints`, the state lane replaces `state`; nothing merges deeper. */
|
|
@@ -93,9 +97,8 @@ export declare function overlay(entity: SceneEntity, row: LiveRow): SceneEntity;
|
|
|
93
97
|
export declare function liveValue(row: LiveRow): SceneEntityLive;
|
|
94
98
|
/** `id` as the entities show it: its live row over its authored entity, or a live entity's own row. */
|
|
95
99
|
export declare function mergedOf(authored: Entities, live: LiveTable, id: string): SceneEntity | undefined;
|
|
96
|
-
type FeedKind = "
|
|
100
|
+
type FeedKind = "removals" | "denied" | "states";
|
|
97
101
|
interface FeedItems {
|
|
98
|
-
changes: SceneDiffOp[];
|
|
99
102
|
removals: LiveRemoved[];
|
|
100
103
|
denied: string[];
|
|
101
104
|
states: SceneState;
|
|
@@ -129,8 +132,10 @@ export declare class Mirror {
|
|
|
129
132
|
epoch: string | undefined;
|
|
130
133
|
version: number;
|
|
131
134
|
hash: string;
|
|
132
|
-
/** An authored diff skipped a version;
|
|
133
|
-
gap:
|
|
135
|
+
/** An authored diff skipped a version (not applied; the track is read again from its snapshot): the highest version seen then. Cleared once the copy is back at it (PLAN v0.34 §2.2). */
|
|
136
|
+
gap: number | undefined;
|
|
137
|
+
/** The live track's first keyframe of the incarnation is in the copy. */
|
|
138
|
+
liveKeyed: boolean;
|
|
134
139
|
pending: number;
|
|
135
140
|
authored: Entities;
|
|
136
141
|
live: LiveTable;
|
|
@@ -143,12 +148,16 @@ export declare class Mirror {
|
|
|
143
148
|
dropHandle(id: number): void;
|
|
144
149
|
/** The hierarchy now (recomputed only after a change of the ids, a parent or an order; the same object while equal). */
|
|
145
150
|
tree(): SceneTree;
|
|
146
|
-
/** A snapshot of incarnation `epoch` replaces the authored copy
|
|
151
|
+
/** A snapshot of incarnation `epoch` replaces the authored copy. The first one is not yet `attached`: that is the task's, once the copy is at the version the open answered. */
|
|
147
152
|
applySnapshot(epoch: string, s: Snapshot): void;
|
|
148
|
-
/** The
|
|
153
|
+
/** The copy is current as of the attach (the task checked it): `attached`. */
|
|
149
154
|
attach(): void;
|
|
150
|
-
/**
|
|
151
|
-
|
|
155
|
+
/**
|
|
156
|
+
* One applied batch: its ops folded into the authored copy, when it is the next version. Otherwise it is not applied
|
|
157
|
+
* (`false`): a gap, `synced` false until the copy is back at the version seen; the reader reads the track again from
|
|
158
|
+
* its snapshot (PLAN v0.34 §2.2).
|
|
159
|
+
*/
|
|
160
|
+
applyDiff(d: Diff, warn: Warn): boolean;
|
|
152
161
|
/** A keyframe replaces the live table. */
|
|
153
162
|
applyKeyframe(k: LiveFrame): void;
|
|
154
163
|
/** One tick folded into the live table; its removals go to the feeds. */
|
|
@@ -156,7 +165,7 @@ export declare class Mirror {
|
|
|
156
165
|
/** Ids of this node's live rows the runtime dropped. */
|
|
157
166
|
denied(ids: string[]): void;
|
|
158
167
|
setPending(n: number): void;
|
|
159
|
-
/** No incarnation: the copy empties
|
|
168
|
+
/** No incarnation: the copy empties, `detached`. */
|
|
160
169
|
detach(): void;
|
|
161
170
|
/** The end: emptied, `closed` (`reason` recorded), every feed ended. */
|
|
162
171
|
close(reason: string): void;
|
|
@@ -174,12 +183,23 @@ type Event = {
|
|
|
174
183
|
} | {
|
|
175
184
|
kind: "nodeEnded";
|
|
176
185
|
}
|
|
186
|
+
/** The answer of `synapse/scene/open` of attempt `attempt`. */
|
|
187
|
+
| {
|
|
188
|
+
kind: "opened";
|
|
189
|
+
attempt: number;
|
|
190
|
+
result: Result<unknown>;
|
|
191
|
+
}
|
|
177
192
|
/** The reader applied an authored frame of incarnation `epoch`: the mirror is at `version`. */
|
|
178
193
|
| {
|
|
179
194
|
kind: "applied";
|
|
180
195
|
epoch: string;
|
|
181
196
|
version: number;
|
|
182
197
|
}
|
|
198
|
+
/** The reader applied the live track's first keyframe of incarnation `epoch`. */
|
|
199
|
+
| {
|
|
200
|
+
kind: "liveKeyed";
|
|
201
|
+
epoch: string;
|
|
202
|
+
}
|
|
183
203
|
/** The reader of attempt `attempt` ended: the incarnation it bound and its final frame's reason (none: the tracks or the session went). */
|
|
184
204
|
| {
|
|
185
205
|
kind: "followEnded";
|
|
@@ -210,9 +230,47 @@ type Event = {
|
|
|
210
230
|
} | {
|
|
211
231
|
kind: "paced";
|
|
212
232
|
attempt: number;
|
|
233
|
+
}
|
|
234
|
+
/** `live.upsert`: a live entity's claim (its args, no id); answered with the id the runtime decided. */
|
|
235
|
+
| {
|
|
236
|
+
kind: "upsert";
|
|
237
|
+
args: Record<string, unknown>;
|
|
238
|
+
reply: Deferred<string>;
|
|
239
|
+
}
|
|
240
|
+
/** `live.remove`. */
|
|
241
|
+
| {
|
|
242
|
+
kind: "remove";
|
|
243
|
+
id: string;
|
|
244
|
+
reply: Deferred<void>;
|
|
245
|
+
}
|
|
246
|
+
/** A lane write asked the claim of `id` (marked asked by the handle). */
|
|
247
|
+
| {
|
|
248
|
+
kind: "claim";
|
|
249
|
+
id: string;
|
|
250
|
+
}
|
|
251
|
+
/** The runtime's answer to a claim asked in attach `bind`. */
|
|
252
|
+
| {
|
|
253
|
+
kind: "claimDone";
|
|
254
|
+
ask: Ask;
|
|
255
|
+
bind: number;
|
|
256
|
+
result: Result<unknown>;
|
|
257
|
+
}
|
|
258
|
+
/** A refused live entity may be due to be asked again. */
|
|
259
|
+
| {
|
|
260
|
+
kind: "reclaim";
|
|
213
261
|
} | {
|
|
214
262
|
kind: "close";
|
|
215
263
|
};
|
|
264
|
+
/** A claim being asked: a `live.upsert` (its args, its caller), or one of this node's claims asked again. */
|
|
265
|
+
type Ask = {
|
|
266
|
+
kind: "first";
|
|
267
|
+
args: Record<string, unknown>;
|
|
268
|
+
reply: Deferred<string>;
|
|
269
|
+
token: number;
|
|
270
|
+
} | {
|
|
271
|
+
kind: "again";
|
|
272
|
+
id: string;
|
|
273
|
+
};
|
|
216
274
|
/** This node's live writer: the session's `<prefix>/scene/live` broadcast and its track `live`. */
|
|
217
275
|
interface LiveWriter {
|
|
218
276
|
session: Session;
|
|
@@ -220,6 +278,51 @@ interface LiveWriter {
|
|
|
220
278
|
stream: StreamWriter;
|
|
221
279
|
seq: number;
|
|
222
280
|
}
|
|
281
|
+
/** Where one of this node's claims stands in the bound incarnation. */
|
|
282
|
+
type ClaimState =
|
|
283
|
+
/** Not claimed in the bound incarnation (none bound, or not asked yet). */
|
|
284
|
+
{
|
|
285
|
+
kind: "unclaimed";
|
|
286
|
+
}
|
|
287
|
+
/** Asked (or about to be, by the task): lane rows are parked until the answer. */
|
|
288
|
+
| {
|
|
289
|
+
kind: "asking";
|
|
290
|
+
}
|
|
291
|
+
/** The runtime granted it in the bound incarnation: lane rows go out. */
|
|
292
|
+
| {
|
|
293
|
+
kind: "claimed";
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Asked again from `at` (`performance.now()` ms) on. `refused`: the runtime refused it (rows are dropped until then; a
|
|
297
|
+
* live entity is asked by the task's timer, an override by its next lane write once due); not refused: a transient
|
|
298
|
+
* answer (rows keep parking; the task's timer asks it).
|
|
299
|
+
*/
|
|
300
|
+
| {
|
|
301
|
+
kind: "paced";
|
|
302
|
+
at: number;
|
|
303
|
+
refused: boolean;
|
|
304
|
+
};
|
|
305
|
+
/** The latest lane rows of one id written while its claim is not answered yet: one slot per lane, latest wins (state, not history), sent once the claim is granted, dropped on a refusal. */
|
|
306
|
+
interface Parked {
|
|
307
|
+
pose?: LivePose;
|
|
308
|
+
joints?: LiveJoints;
|
|
309
|
+
state?: LiveState;
|
|
310
|
+
lifetimeMs?: number;
|
|
311
|
+
}
|
|
312
|
+
/** One of this node's claims: its own intent, never world state. */
|
|
313
|
+
declare class Claim {
|
|
314
|
+
readonly args: Record<string, unknown>;
|
|
315
|
+
state: ClaimState;
|
|
316
|
+
/** Refusals of it in a row (the pace of the next ask). */
|
|
317
|
+
refusals: number;
|
|
318
|
+
parked: Parked;
|
|
319
|
+
/** `args`: the `upsert` call's args besides `id` (a live entity's `kind`, `name`, `parent`, `lifetime_ms` and components); empty for the override of an entity of the scene. */
|
|
320
|
+
constructor(args: Record<string, unknown>, state: ClaimState);
|
|
321
|
+
/** A live entity (claimed again on every attach), not an override (claimed by its lanes). */
|
|
322
|
+
get isEntity(): boolean;
|
|
323
|
+
}
|
|
324
|
+
/** What the lane gate does with a row: sent now (claimed), parked (the claim is not answered yet), dropped and counted (refused, not due again). */
|
|
325
|
+
type Gate = "send" | "park" | "drop";
|
|
223
326
|
/** The node's scene: what every handle shares with the task. */
|
|
224
327
|
export declare class Scene {
|
|
225
328
|
readonly node: Node;
|
|
@@ -230,11 +333,24 @@ export declare class Scene {
|
|
|
230
333
|
/** Handles neither closed nor dropped; the one that brings it to 0 tells the task `close`. */
|
|
231
334
|
handles: number;
|
|
232
335
|
nextHandle: number;
|
|
233
|
-
/** The live writer of the current session, made on the first
|
|
336
|
+
/** The live writer of the current session, made on the first live write. */
|
|
234
337
|
writer: LiveWriter | undefined;
|
|
338
|
+
/** This node's claims by id (what `live.upsert` made and what lane writes asked for); `live.remove` drops one. Nothing else is kept. */
|
|
339
|
+
readonly claims: Map<string, Claim>;
|
|
235
340
|
detachedDrops: number;
|
|
341
|
+
/** Lane rows dropped because their id's claim was refused (and not due again), or parked rows a refusal dropped. */
|
|
342
|
+
unclaimedDrops: number;
|
|
343
|
+
/** Told when a counter of the status changes (the listeners of the status state values). */
|
|
344
|
+
readonly counters: Set<() => void>;
|
|
236
345
|
constructor(node: Node, warn: Warn);
|
|
237
346
|
post(e: Event): boolean;
|
|
347
|
+
countersChanged(): void;
|
|
348
|
+
/**
|
|
349
|
+
* What happens to a lane row of `id` now. An id with no claim becomes the override's claim; an override that is
|
|
350
|
+
* unclaimed, or refused and due again, is marked asked and returned in `ask` (the task asks it: one ask per id at a
|
|
351
|
+
* time). A live entity's claim is asked by the task (on attach, paced after a refusal), never by a lane.
|
|
352
|
+
*/
|
|
353
|
+
gate(id: string, now: number, ask: string[]): Gate;
|
|
238
354
|
request<T>(make: (reply: Deferred<T>) => Event): Promise<T>;
|
|
239
355
|
}
|
|
240
356
|
/** The node's one scene task, if any (set with the task, cleared by the task when it exits). */
|
|
@@ -246,54 +362,43 @@ export declare function startScene(scene: Scene, registry: SceneRegistry): void;
|
|
|
246
362
|
export declare class SceneHandleImpl implements SceneHandle {
|
|
247
363
|
#private;
|
|
248
364
|
private readonly scene;
|
|
365
|
+
/** The authored plane's verbs. */
|
|
366
|
+
readonly authored: SceneAuthored;
|
|
367
|
+
/** This node's live writes. */
|
|
368
|
+
readonly live: SceneLive;
|
|
369
|
+
/** The handle's own state, a state value: `get()` (the same object while unchanged), `onChange`, `changed()`, `watch()`. */
|
|
370
|
+
readonly status: StateValue<SceneStatus>;
|
|
249
371
|
constructor(scene: Scene);
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
entity(id: string, opts: {
|
|
255
|
-
plane: "live";
|
|
256
|
-
}): SceneView<SceneEntityLive | undefined>;
|
|
257
|
-
entity(id: string, opts?: {
|
|
258
|
-
plane?: "authored" | "live";
|
|
259
|
-
}): SceneView<SceneEntity | SceneEntityLive | undefined>;
|
|
372
|
+
/** The merged entities now; a closed handle reads nothing (the mirror may live on for the node's other handles). */
|
|
373
|
+
get(): Readonly<Record<string, SceneEntity>>;
|
|
374
|
+
/** One entity as a view: the merged entity, with its authored value (`authored`) and its live row (`live`). */
|
|
375
|
+
entity(ref: SceneEntityRef): SceneEntityView;
|
|
260
376
|
tree(): SceneView<SceneTree>;
|
|
261
377
|
query(where: (e: SceneEntity) => boolean): SceneView<SceneEntity[]>;
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
378
|
+
/** The one boolean a node author checks: `status.get().synced`. */
|
|
379
|
+
get synced(): boolean;
|
|
380
|
+
/** Resolves once the handle is attached (at once if it is); `not_connected` once it is closed (`close()`, or the node ending). */
|
|
381
|
+
ready(): Promise<void>;
|
|
382
|
+
/** The entities after their next change (state, not history); `not_connected` once this handle is closed. */
|
|
383
|
+
changed(): Promise<Readonly<Record<string, SceneEntity>>>;
|
|
384
|
+
/** The entities after each change; ends with the handle. */
|
|
385
|
+
watch(): AsyncIterable<Readonly<Record<string, SceneEntity>>>;
|
|
265
386
|
watchLiveRemovals(cb: (batch: LiveRemoved[]) => void): () => void;
|
|
266
387
|
watchLiveRemovals(): AsyncIterableIterator<LiveRemoved[]>;
|
|
267
388
|
watchLiveDenied(cb: (ids: string[]) => void): () => void;
|
|
268
389
|
watchLiveDenied(): AsyncIterableIterator<string[]>;
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
txn(build: (t: SceneTxn) => void): Promise<void>;
|
|
273
|
-
spawn(kind: string, opts: SceneSpawnOptions): Promise<string>;
|
|
274
|
-
patch(id: string, set: Partial<SceneEntity>): Promise<void>;
|
|
275
|
-
rename(id: string, name: string): Promise<void>;
|
|
276
|
-
reparent(id: string, parent: string | null, place?: ScenePlace): Promise<void>;
|
|
277
|
-
despawn(id: string, opts?: {
|
|
278
|
-
cascade?: boolean;
|
|
279
|
-
}): Promise<void>;
|
|
280
|
-
setLocked(id: string, locked: boolean): Promise<void>;
|
|
281
|
-
/**
|
|
282
|
-
* Writes one live batch on this node's live track (made on the first call of each session); returns
|
|
283
|
-
* at once, like `publish`. The runtime stamps the rows and owns the outcome: an id another writer owns
|
|
284
|
-
* comes back on `watchLiveDenied`, a malformed batch as a node notice. Not attached: dropped and counted.
|
|
285
|
-
*/
|
|
286
|
-
live(batch: LiveBatch): void;
|
|
287
|
-
/** The framework bridge (React's hooks): called on every change of the entities or the status. */
|
|
288
|
-
subscribe(listener: () => void): () => void;
|
|
289
|
-
/** Closes the handle: its verbs fail, its views and feeds end, its status says `closed`; the node's other scene handles go on. The last one ends the task, which ends this node's live writer (the runtime retracts its lifetimed rows and live entities: `writer_gone`). Idempotent. */
|
|
390
|
+
/** `cb` with the entities on every change of the entities or the status (the framework bridge, React's hooks), and once more when this handle closes; returns the remover. */
|
|
391
|
+
onChange(cb: (entities: Readonly<Record<string, SceneEntity>>) => void): () => void;
|
|
392
|
+
/** Closes the handle: its verbs fail, its views and feeds end, its status says `closed`; the node's other scene handles go on. The last one ends the task, which releases this node's claims (one `synapse/scene/live/remove` call per claim, best effort, not awaited; the session's end releases what remains) and ends its live writer. Idempotent. */
|
|
290
393
|
close(): void;
|
|
291
394
|
[Symbol.asyncDispose](): Promise<void>;
|
|
292
395
|
}
|
|
293
396
|
/**
|
|
294
397
|
* The active project's scene (one per project; one task per node, shared by every handle). Resolves
|
|
295
|
-
* once the handle is attached
|
|
296
|
-
*
|
|
398
|
+
* once the handle is attached (the copy at the version `synapse/scene/open` answered, or past it), or at
|
|
399
|
+
* once `detached` when the runtime says no project is active; the
|
|
400
|
+
* handle then follows the incarnations as they come and go. Without a session (before the first, between
|
|
401
|
+
* two) the task waits for the next one, like after a drop.
|
|
297
402
|
*/
|
|
298
403
|
export declare function openScene(node: Node, registry: SceneRegistry, warn: Warn): Promise<SceneHandleImpl>;
|
|
299
404
|
export {};
|