@pinecall/room 0.1.0 → 0.1.1

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
@@ -11,7 +11,7 @@ that change it. The package has three entry points, and each one is for a differ
11
11
 
12
12
  | import | where it runs | what it gives you |
13
13
  |---|---|---|
14
- | `@pinecall/room` | the page | `room()`, the store of one conversation, and `rowsOf`, `knownBy`, `brief` to draw it |
14
+ | `@pinecall/room` | the page | `room()`, the store of one conversation, `rowsOf`, `knownBy`, `brief` to draw it, and the karaoke of what is being said |
15
15
  | `@pinecall/room/react` | the page, in React | `useRoom()` and `useStore()` |
16
16
  | `@pinecall/room/server` | your server | `mint()`, `dial()` and `GatewayRefused`: the only code that touches the key |
17
17
 
@@ -246,6 +246,44 @@ as one short line each, `status` (`running`, `done`, `failed`) and `error` — a
246
246
  `[name, value]` pairs with the empty ones left out. `brief(value, max)` is a value as one line of
247
247
  JSON, cut at `max` characters. A field that is an object is opened one level — `person.name`, `person.email` — so a page shows a name rather than a JSON blob.
248
248
 
249
+ ## What is being said right now
250
+
251
+ Both sides of a spoken call can be drawn as they happen, karaoke-style.
252
+
253
+ **The visitor** — `state.log.live.user` is what the recogniser has heard so far of the turn in
254
+ progress, rewritten as they speak ("Hi", "Hi ther", "Hi there. I would…"), and `null` once the
255
+ turn closes.
256
+
257
+ **The agent** — a voice call's log carries its reply one word at a time, each with the second it
258
+ is spoken at. The words usually reach the page before the voice says them, so a page can draw the
259
+ whole sentence and light each word as it sounds:
260
+
261
+ ```tsx
262
+ import { useKaraoke } from "@pinecall/room/react";
263
+
264
+ const saying = useKaraoke(room.entries); // null when nobody is mid-reply
265
+ {saying && <p><b>{saying.lit}</b><span className="dim">{saying.coming}</span></p>}
266
+ ```
267
+
268
+ Without React, the same with a clock of your own: note the time the reply's first word arrived,
269
+ and on each frame split it with `litAt`.
270
+
271
+ ```ts
272
+ import { litAt, sayingOf } from "@pinecall/room";
273
+
274
+ let began: { speech: string; at: number } | null = null;
275
+ function frame() {
276
+ const saying = sayingOf(call.state.entries);
277
+ if (saying && began?.speech !== saying.speech) began = { speech: saying.speech, at: performance.now() };
278
+ if (saying && began) draw(litAt(saying, performance.now() - began.at)); // { lit, coming }
279
+ requestAnimationFrame(frame);
280
+ }
281
+ ```
282
+
283
+ A written call's reply comes as model tokens with no timing: every token is lit as it arrives,
284
+ which reads as the agent typing. Once the turn closes, the reply is a turn in `rowsOf` like any
285
+ other, and `useKaraoke` returns `null`.
286
+
249
287
  ## Sound and the browser's permission
250
288
 
251
289
  In `talk`, the microphone is turned on once the room is joined, and the agent's voice plays through
package/dist/index.d.ts CHANGED
@@ -6,4 +6,5 @@ export type { Connection } from "./log/follow.js";
6
6
  export type { Speaking } from "./seat/join.js";
7
7
  export type { LivekitModule } from "./seat/livekit.js";
8
8
  export { brief, knownBy, rowsOf, type Row } from "./rows.js";
9
+ export { joined, litAt, sayingOf, soundedBy, type Lit, type Saying, type Word } from "./karaoke.js";
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mGAAmG;AAEnG,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACxF,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,GAAG,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mGAAmG;AAEnG,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACxF,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,GAAG,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,GAAG,EAAE,KAAK,MAAM,EAAE,KAAK,IAAI,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  /** @pinecall/room: the caller's side of a Pinecall call in a browser — one store, no framework. */
2
2
  export { room } from "./room.js";
3
3
  export { brief, knownBy, rowsOf } from "./rows.js";
4
+ export { joined, litAt, sayingOf, soundedBy } from "./karaoke.js";
4
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mGAAmG;AAEnG,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAMjC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAY,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mGAAmG;AAEnG,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAMjC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAY,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAoC,MAAM,cAAc,CAAC"}
@@ -0,0 +1,29 @@
1
+ /** The agent's reply while it is being said: its words as the log delivers them, and which have sounded. */
2
+ import { type Entry } from "@pinecall/protocol";
3
+ /** One delta of the reply: a word (voice) or a token (text), and when it sounds, if it does. */
4
+ export interface Word {
5
+ text: string;
6
+ start: number | null;
7
+ }
8
+ /** The reply in progress: its speech id and every delta so far. */
9
+ export interface Saying {
10
+ speech: string;
11
+ words: Word[];
12
+ }
13
+ /** A reply split where the voice is: what has sounded, and what is still to come. */
14
+ export interface Lit {
15
+ lit: string;
16
+ coming: string;
17
+ }
18
+ /** The reply being said now, read back from the newest entry to the last closed turn; null when nobody is mid-reply. */
19
+ export declare function sayingOf(entries: readonly Entry[]): Saying | null;
20
+ /**
21
+ * How many words have sounded `elapsed` ms after the reply's first word reached the page. A word
22
+ * with no timing is lit at once; the count never skips a word, so a late one holds back the rest.
23
+ */
24
+ export declare function soundedBy(words: readonly Word[], elapsed: number): number;
25
+ /** The deltas as one line, the way the wire's reducer joins them: a timed word is its own word. */
26
+ export declare function joined(words: readonly Word[]): string;
27
+ /** The reply split at `elapsed` ms: the words that have sounded, and the rest. */
28
+ export declare function litAt(saying: Saying, elapsed: number): Lit;
29
+ //# sourceMappingURL=karaoke.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"karaoke.d.ts","sourceRoot":"","sources":["../src/karaoke.ts"],"names":[],"mappings":"AAAA,4GAA4G;AAQ5G,OAAO,EAAyB,KAAK,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEvE,gGAAgG;AAChG,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,mEAAmE;AACnE,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED,qFAAqF;AACrF,MAAM,WAAW,GAAG;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wHAAwH;AACxH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,SAAS,KAAK,EAAE,GAAG,MAAM,GAAG,IAAI,CAgBjE;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAOzE;AAED,mGAAmG;AACnG,wBAAgB,MAAM,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,MAAM,CAQrD;AAED,kFAAkF;AAClF,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,GAAG,CAG1D"}
@@ -0,0 +1,64 @@
1
+ /** The agent's reply while it is being said: its words as the log delivers them, and which have sounded. */
2
+ //
3
+ // A voice call delivers one agent.transcript per word, each with `start`: the second, from the
4
+ // top of the reply, at which the voice says it (the TTS measures it; the runtime passes it on).
5
+ // A word is lit when the clock reaches it, so the words on screen are the words in the ear. A
6
+ // written call's deltas are model tokens with no timing: they are lit the moment they arrive.
7
+ // The visitor's side needs nothing here: `state.log.live.user` is what the ear has heard so far.
8
+ import { AgentTranscriptSchema } from "@pinecall/protocol";
9
+ /** The reply being said now, read back from the newest entry to the last closed turn; null when nobody is mid-reply. */
10
+ export function sayingOf(entries) {
11
+ const words = [];
12
+ let speech = null;
13
+ for (let at = entries.length - 1; at >= 0; at -= 1) {
14
+ const entry = entries[at];
15
+ if (entry === undefined || entry.type === "turn.agent")
16
+ break;
17
+ if (entry.type !== "agent.transcript")
18
+ continue;
19
+ const delta = AgentTranscriptSchema.safeParse(entry.data);
20
+ if (!delta.success)
21
+ continue;
22
+ if (delta.data.final)
23
+ break;
24
+ // Only the newest reply: a delta of an earlier speech is a reply that already closed.
25
+ if (speech === null)
26
+ speech = delta.data.speech_id;
27
+ else if (delta.data.speech_id !== speech)
28
+ break;
29
+ words.unshift({ text: delta.data.text, start: delta.data.start ?? null });
30
+ }
31
+ return speech === null ? null : { speech, words };
32
+ }
33
+ /**
34
+ * How many words have sounded `elapsed` ms after the reply's first word reached the page. A word
35
+ * with no timing is lit at once; the count never skips a word, so a late one holds back the rest.
36
+ */
37
+ export function soundedBy(words, elapsed) {
38
+ let lit = 0;
39
+ for (const word of words) {
40
+ if (word.start !== null && word.start * 1000 > elapsed)
41
+ break;
42
+ lit += 1;
43
+ }
44
+ return lit;
45
+ }
46
+ /** The deltas as one line, the way the wire's reducer joins them: a timed word is its own word. */
47
+ export function joined(words) {
48
+ let line = "";
49
+ for (const word of words) {
50
+ if (line === "")
51
+ line = word.text;
52
+ else if (word.start !== null && !/\s$/.test(line) && !/^\s/.test(word.text))
53
+ line = `${line} ${word.text}`;
54
+ else
55
+ line = `${line}${word.text}`;
56
+ }
57
+ return line;
58
+ }
59
+ /** The reply split at `elapsed` ms: the words that have sounded, and the rest. */
60
+ export function litAt(saying, elapsed) {
61
+ const lit = joined(saying.words.slice(0, soundedBy(saying.words, elapsed)));
62
+ return { lit, coming: joined(saying.words).slice(lit.length) };
63
+ }
64
+ //# sourceMappingURL=karaoke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"karaoke.js","sourceRoot":"","sources":["../src/karaoke.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /** @pinecall/room/react: a store read the way React reads one, and one room per mounted component. */
2
- import { type RoomOptions, type RoomState, type RoomStore, type Store } from "../index.js";
2
+ import { type Lit, type RoomOptions, type RoomState, type RoomStore, type Store } from "../index.js";
3
3
  /** The store's state, re-rendering when it changes. Any store of this package. */
4
4
  export declare function useStore<T>(store: Store<T>): T;
5
5
  /** What `useRoom` hands a component: the state, and the verbs to change it. */
@@ -10,4 +10,10 @@ export type RoomHandle = RoomState & Pick<RoomStore, "start" | "send" | "callMe"
10
10
  * is the one that runs.
11
11
  */
12
12
  export declare function useRoom(options: RoomOptions): RoomHandle;
13
+ /**
14
+ * The agent's reply as the voice says it: `lit` has sounded, `coming` has not, or null when nobody
15
+ * is mid-reply. The clock starts when the reply's first word reaches the page and ticks one frame
16
+ * at a time only while a word is still due. Pass `state.entries` of a live room.
17
+ */
18
+ export declare function useKaraoke(entries: RoomState["entries"]): Lit | null;
13
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,sGAAsG;AAItG,OAAO,EAAQ,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAEjG,kFAAkF;AAClF,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAI9C;AAED,+EAA+E;AAC/E,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,WAAW,CAAC,CAAC;AAE1G;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,CAuBxD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,sGAAsG;AAItG,OAAO,EAAyB,KAAK,GAAG,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAE5H,kFAAkF;AAClF,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAI9C;AAED,+EAA+E;AAC/E,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,WAAW,CAAC,CAAC;AAE1G;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,CAuBxD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,GAAG,GAAG,IAAI,CAqBpE"}
@@ -1,6 +1,6 @@
1
1
  /** @pinecall/room/react: a store read the way React reads one, and one room per mounted component. */
2
2
  import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from "react";
3
- import { room } from "../index.js";
3
+ import { litAt, room, sayingOf } from "../index.js";
4
4
  /** The store's state, re-rendering when it changes. Any store of this package. */
5
5
  export function useStore(store) {
6
6
  const subscribe = useCallback((changed) => store.subscribe(changed), [store]);
@@ -36,6 +36,32 @@ export function useRoom(options) {
36
36
  const { start, send, callMe, leave, playSound } = store;
37
37
  return { ...state, start, send, callMe, leave, playSound };
38
38
  }
39
+ /**
40
+ * The agent's reply as the voice says it: `lit` has sounded, `coming` has not, or null when nobody
41
+ * is mid-reply. The clock starts when the reply's first word reaches the page and ticks one frame
42
+ * at a time only while a word is still due. Pass `state.entries` of a live room.
43
+ */
44
+ export function useKaraoke(entries) {
45
+ const saying = sayingOf(entries);
46
+ const began = useRef(null);
47
+ const [now, setNow] = useState(() => performance.now());
48
+ if (saying === null)
49
+ began.current = null;
50
+ else if (began.current?.speech !== saying.speech)
51
+ began.current = { speech: saying.speech, at: performance.now() };
52
+ const split = saying === null || saying.words.length === 0 ? null : litAt(saying, now - (began.current?.at ?? now));
53
+ const waiting = split !== null && split.coming !== "";
54
+ useEffect(() => {
55
+ if (!waiting)
56
+ return;
57
+ let frame = requestAnimationFrame(function tick() {
58
+ setNow(performance.now());
59
+ frame = requestAnimationFrame(tick);
60
+ });
61
+ return () => cancelAnimationFrame(frame);
62
+ }, [waiting]);
63
+ return split;
64
+ }
39
65
  /** Options whose every field is the one the component rendered last. */
40
66
  function readingLatest(latest) {
41
67
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,sGAAsG;AAEtG,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAEvF,OAAO,EAAE,IAAI,EAAgE,MAAM,aAAa,CAAC;AAEjG,kFAAkF;AAClF,MAAM,UAAU,QAAQ,CAAI,KAAe;IACzC,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,OAAmB,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1F,MAAM,IAAI,GAAG,GAAM,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC;IAClC,OAAO,oBAAoB,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACrD,CAAC;AAKD;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,OAAoB;IAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1B,SAAS,CAAC,GAAG,EAAE;QACb,4FAA4F;QAC5F,oDAAoD;QACpD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACtC,OAAO;QACT,CAAC;QACD,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YACrB,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IACZ,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9B,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IACxD,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAC7D,CAAC;AAED,wEAAwE;AACxE,SAAS,aAAa,CAAC,MAAyC;IAC9D,OAAO;QACL,IAAI,MAAM;YACR,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QAC/B,CAAC;QACD,IAAI,GAAG;YACL,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;QAC5B,CAAC;QACD,IAAI,MAAM;YACR,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QAC/B,CAAC;QACD,IAAI,MAAM;YACR,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QAC/B,CAAC;QACD,IAAI,KAAK;YACP,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;QAC9B,CAAC;QACD,IAAI,OAAO;YACT,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;QAChC,CAAC;QACD,IAAI,SAAS;YACX,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;QAClC,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pinecall/room",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "The caller's side of a Pinecall call in a browser: one store, the seat and the log joined, no framework",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Pinecall <hello@pinecall.io>",