@haikit/react 0.11.0 → 0.13.0

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
@@ -57,6 +57,23 @@ contract the server implements:
57
57
  Import the contract with `import type`. Only the types are needed, so the
58
58
  schemas and their library stay out of the browser bundle.
59
59
 
60
+ ## Notices
61
+
62
+ `reactNotice` does the same for a notice, from the same `defineNotice` contract
63
+ the server sends it with. `NoticeProps<typeof yourNotice>` gives the component
64
+ `payload`, typed from the contract, its `seq`, and the `handle` of the surface
65
+ it sits beside, if any. There is no `send`: a notice cannot reach the server.
66
+
67
+ ```tsx
68
+ import type { holdConfirmed } from "../shared/notices";
69
+
70
+ function HoldConfirmed({ payload }: NoticeProps<typeof holdConfirmed>) {
71
+ return <p>Fare held · {payload.flightId} · ref {payload.reference}</p>;
72
+ }
73
+
74
+ mountChat({ root, registry, notices: { hold_confirmed: reactNotice(HoldConfirmed) } });
75
+ ```
76
+
60
77
  ## Lifecycle
61
78
 
62
79
  The default transcript mounts a surface **once**, so `useState` survives the
package/dist/index.d.ts CHANGED
@@ -10,8 +10,8 @@
10
10
  * prop or an action that changes there stops this side compiling.
11
11
  */
12
12
  import { type ComponentType } from "react";
13
- import type { ComponentDef, SurfaceMode, SurfaceState } from "@haikit/client";
14
- import type { ActionMap, Infer, QueryMap, Surface } from "@haikit/core";
13
+ import type { ComponentDef, NoticeDef, SurfaceMode, SurfaceState } from "@haikit/client";
14
+ import type { ActionMap, Infer, Notice, QueryMap, Surface } from "@haikit/core";
15
15
  type AnySurface = Surface<any, ActionMap, QueryMap>;
16
16
  type PropsOf<S> = S extends Surface<infer P, any, any> ? P : never;
17
17
  type ActionsOf<S> = S extends Surface<any, infer A, any> ? A : never;
@@ -46,5 +46,22 @@ export interface SurfaceProps<S extends AnySurface> {
46
46
  * unmounted when the surface goes away, so effects clean up after themselves.
47
47
  */
48
48
  export declare function reactSurface<S extends AnySurface>(Component: ComponentType<SurfaceProps<S>>): ComponentDef<PropsOf<S>>;
49
+ type AnyNotice = Notice<any>;
50
+ type PayloadOf<N> = N extends Notice<infer P> ? P : never;
51
+ /** What a React notice component receives, typed from its notice contract. */
52
+ export interface NoticeProps<N extends AnyNotice> {
53
+ /** The notice's payload, as its `payload` schema produced it. */
54
+ payload: PayloadOf<N>;
55
+ /** Its sequence number in the conversation. */
56
+ seq: number;
57
+ /** The surface it is shown beside, if any. */
58
+ handle?: string;
59
+ }
60
+ /**
61
+ * A notices registry entry that renders `Component` into the notice's element.
62
+ * As with `reactSurface`, the first render is synchronous and the root is
63
+ * unmounted when the notice goes away. A notice has no `send`.
64
+ */
65
+ export declare function reactNotice<N extends AnyNotice>(Component: ComponentType<NoticeProps<N>>): NoticeDef<PayloadOf<N>>;
49
66
  export {};
50
67
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAG1D,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAExE,KAAK,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AACpD,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AACnE,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAErE,gFAAgF;AAChF,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,UAAU;IAChD,gEAAgE;IAChE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAClB;;;;OAIG;IACH,IAAI,EAAE,WAAW,CAAC;IAClB,4EAA4E;IAC5E,KAAK,EAAE,YAAY,CAAC;IACpB,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gFAAgF;IAChF,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/G;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,UAAU,EAAE,SAAS,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CA4CtH"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAG1D,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACzF,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEhF,KAAK,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AACpD,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AACnE,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAErE,gFAAgF;AAChF,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,UAAU;IAChD,gEAAgE;IAChE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAClB;;;;OAIG;IACH,IAAI,EAAE,WAAW,CAAC;IAClB,4EAA4E;IAC5E,KAAK,EAAE,YAAY,CAAC;IACpB,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gFAAgF;IAChF,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/G;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,UAAU,EAAE,SAAS,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CA4CtH;AAED,KAAK,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;AAC7B,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAE1D,8EAA8E;AAC9E,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,SAAS;IAC9C,iEAAiE;IACjE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IACtB,+CAA+C;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,SAAS,EAAE,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAiBlH"}
package/dist/index.js CHANGED
@@ -63,4 +63,28 @@ export function reactSurface(Component) {
63
63
  },
64
64
  };
65
65
  }
66
+ /**
67
+ * A notices registry entry that renders `Component` into the notice's element.
68
+ * As with `reactSurface`, the first render is synchronous and the root is
69
+ * unmounted when the notice goes away. A notice has no `send`.
70
+ */
71
+ export function reactNotice(Component) {
72
+ return {
73
+ mount(element, payload, ctx) {
74
+ const root = createRoot(element);
75
+ try {
76
+ flushSync(() => root.render(createElement(Component, { payload, seq: ctx.seq, handle: ctx.handle })));
77
+ }
78
+ catch (err) {
79
+ root.unmount();
80
+ throw err;
81
+ }
82
+ return {
83
+ unmount() {
84
+ root.unmount();
85
+ },
86
+ };
87
+ },
88
+ };
89
+ }
66
90
  //# 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;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAsB,MAAM,OAAO,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AA+BtC;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAuB,SAAyC;IAC1F,OAAO;QACL,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG;YACvB,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;YACjC,IAAI,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;YACtB,wCAAwC;YACxC,IAAI,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;YAC9B,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,MAAM,IAAI,GAAG,GAAG,EAAE,CAChB,IAAI,CAAC,MAAM,CACT,aAAa,CAAC,SAAS,EAAE;gBACvB,KAAK;gBACL,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,KAAK;gBACL,SAAS;gBACT,OAAO;gBACP,IAAI,EAAE,GAAG,CAAC,IAA+B;aAC1C,CAAC,CACH,CAAC;YACJ,wEAAwE;YACxE,yEAAyE;YACzE,qEAAqE;YACrE,IAAI,CAAC;gBACH,SAAS,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,MAAM,GAAG,CAAC;YACZ,CAAC;YACD,OAAO;gBACL,MAAM,CAAC,MAAM;oBACX,KAAK,GAAG,QAAQ,CAAC;oBACjB,SAAS,GAAG,MAAM,CAAC;oBACnB,IAAI,EAAE,CAAC;gBACT,CAAC;gBACD,MAAM;oBACJ,OAAO,GAAG,IAAI,CAAC;oBACf,IAAI,EAAE,CAAC;gBACT,CAAC;gBACD,OAAO;oBACL,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,CAAC;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAsB,MAAM,OAAO,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AA+BtC;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAuB,SAAyC;IAC1F,OAAO;QACL,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG;YACvB,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;YACjC,IAAI,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;YACtB,wCAAwC;YACxC,IAAI,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;YAC9B,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,MAAM,IAAI,GAAG,GAAG,EAAE,CAChB,IAAI,CAAC,MAAM,CACT,aAAa,CAAC,SAAS,EAAE;gBACvB,KAAK;gBACL,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,KAAK;gBACL,SAAS;gBACT,OAAO;gBACP,IAAI,EAAE,GAAG,CAAC,IAA+B;aAC1C,CAAC,CACH,CAAC;YACJ,wEAAwE;YACxE,yEAAyE;YACzE,qEAAqE;YACrE,IAAI,CAAC;gBACH,SAAS,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,MAAM,GAAG,CAAC;YACZ,CAAC;YACD,OAAO;gBACL,MAAM,CAAC,MAAM;oBACX,KAAK,GAAG,QAAQ,CAAC;oBACjB,SAAS,GAAG,MAAM,CAAC;oBACnB,IAAI,EAAE,CAAC;gBACT,CAAC;gBACD,MAAM;oBACJ,OAAO,GAAG,IAAI,CAAC;oBACf,IAAI,EAAE,CAAC;gBACT,CAAC;gBACD,OAAO;oBACL,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,CAAC;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AAeD;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAsB,SAAwC;IACvF,OAAO;QACL,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG;YACzB,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;YACjC,IAAI,CAAC;gBACH,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;YACxG,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,MAAM,GAAG,CAAC;YACZ,CAAC;YACD,OAAO;gBACL,OAAO;oBACL,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,CAAC;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haikit/react",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "Write haikit surface components in React: typed props and actions from the shared surface contract.",
5
5
  "keywords": [
6
6
  "haikit",
@@ -28,8 +28,8 @@
28
28
  "prepack": "npm --prefix ../.. run build"
29
29
  },
30
30
  "dependencies": {
31
- "@haikit/client": "0.11.0",
32
- "@haikit/core": "0.11.0"
31
+ "@haikit/client": "0.13.0",
32
+ "@haikit/core": "0.13.0"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "react": "^18.0.0 || ^19.0.0",
package/src/index.ts CHANGED
@@ -13,8 +13,8 @@
13
13
  import { createElement, type ComponentType } from "react";
14
14
  import { createRoot } from "react-dom/client";
15
15
  import { flushSync } from "react-dom";
16
- import type { ComponentDef, SurfaceMode, SurfaceState } from "@haikit/client";
17
- import type { ActionMap, Infer, QueryMap, Surface } from "@haikit/core";
16
+ import type { ComponentDef, NoticeDef, SurfaceMode, SurfaceState } from "@haikit/client";
17
+ import type { ActionMap, Infer, Notice, QueryMap, Surface } from "@haikit/core";
18
18
 
19
19
  type AnySurface = Surface<any, ActionMap, QueryMap>;
20
20
  type PropsOf<S> = S extends Surface<infer P, any, any> ? P : never;
@@ -96,3 +96,40 @@ export function reactSurface<S extends AnySurface>(Component: ComponentType<Surf
96
96
  },
97
97
  };
98
98
  }
99
+
100
+ type AnyNotice = Notice<any>;
101
+ type PayloadOf<N> = N extends Notice<infer P> ? P : never;
102
+
103
+ /** What a React notice component receives, typed from its notice contract. */
104
+ export interface NoticeProps<N extends AnyNotice> {
105
+ /** The notice's payload, as its `payload` schema produced it. */
106
+ payload: PayloadOf<N>;
107
+ /** Its sequence number in the conversation. */
108
+ seq: number;
109
+ /** The surface it is shown beside, if any. */
110
+ handle?: string;
111
+ }
112
+
113
+ /**
114
+ * A notices registry entry that renders `Component` into the notice's element.
115
+ * As with `reactSurface`, the first render is synchronous and the root is
116
+ * unmounted when the notice goes away. A notice has no `send`.
117
+ */
118
+ export function reactNotice<N extends AnyNotice>(Component: ComponentType<NoticeProps<N>>): NoticeDef<PayloadOf<N>> {
119
+ return {
120
+ mount(element, payload, ctx) {
121
+ const root = createRoot(element);
122
+ try {
123
+ flushSync(() => root.render(createElement(Component, { payload, seq: ctx.seq, handle: ctx.handle })));
124
+ } catch (err) {
125
+ root.unmount();
126
+ throw err;
127
+ }
128
+ return {
129
+ unmount() {
130
+ root.unmount();
131
+ },
132
+ };
133
+ },
134
+ };
135
+ }