@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 +17 -0
- package/dist/index.d.ts +19 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +39 -2
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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.
|
|
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.
|
|
32
|
-
"@haikit/core": "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
|
+
}
|