@reactpy/client 1.0.2 → 1.0.3
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/LICENSE +9 -0
- package/dist/bind.d.ts +6 -0
- package/dist/bind.d.ts.map +1 -0
- package/dist/bind.js +53 -0
- package/dist/bind.js.map +1 -0
- package/dist/client.d.ts +29 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +60 -0
- package/dist/client.js.map +1 -0
- package/dist/components.d.ts +10 -0
- package/dist/components.d.ts.map +1 -0
- package/dist/components.js +178 -0
- package/dist/components.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +8 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +7 -0
- package/dist/logger.js.map +1 -0
- package/dist/mount.d.ts +3 -0
- package/dist/mount.d.ts.map +1 -0
- package/dist/mount.js +32 -0
- package/dist/mount.js.map +1 -0
- package/dist/types.d.ts +125 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/vdom.d.ts +8 -0
- package/dist/vdom.d.ts.map +1 -0
- package/dist/vdom.js +254 -0
- package/dist/vdom.js.map +1 -0
- package/dist/websocket.d.ts +6 -0
- package/dist/websocket.d.ts.map +1 -0
- package/dist/websocket.js +57 -0
- package/dist/websocket.js.map +1 -0
- package/package.json +11 -6
- package/tsconfig.json +0 -14
package/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) Reactive Python and affiliates.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/dist/bind.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../src/bind.tsx"],"names":[],"mappings":"AAEA,wBAAsB,2BAA2B,mBAM/B,WAAW;mBA0BV,GAAG,SAAS,GAAG,aAAa,GAAG,EAAE;sBAE9B,GAAG;;GApBxB"}
|
package/dist/bind.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as preact from "preact";
|
|
2
|
+
export async function infer_bind_from_environment() {
|
|
3
|
+
try {
|
|
4
|
+
// @ts-ignore
|
|
5
|
+
const React = await import("react");
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
const ReactDOM = await import("react-dom/client");
|
|
8
|
+
return (node) => reactjs_bind(node, React, ReactDOM);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
console.error("Unknown error occurred: 'react' is missing within this ReactPy environment! \
|
|
12
|
+
Your JavaScript components may not work as expected!");
|
|
13
|
+
return (node) => local_preact_bind(node);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function local_preact_bind(node) {
|
|
17
|
+
return {
|
|
18
|
+
create: (type, props, children) => preact.createElement(type, props, ...(children || [])),
|
|
19
|
+
render: (element) => {
|
|
20
|
+
preact.render(element, node);
|
|
21
|
+
},
|
|
22
|
+
unmount: () => preact.render(null, node),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const roots = new WeakMap();
|
|
26
|
+
function reactjs_bind(node, React, ReactDOM) {
|
|
27
|
+
let root = null;
|
|
28
|
+
return {
|
|
29
|
+
create: (type, props, children) => React.createElement(type, props, ...(children || [])),
|
|
30
|
+
render: (element) => {
|
|
31
|
+
if (!root) {
|
|
32
|
+
if (!roots.get(node)) {
|
|
33
|
+
root = ReactDOM.createRoot(node);
|
|
34
|
+
roots.set(node, root);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
root = roots.get(node);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
root.render(element);
|
|
41
|
+
},
|
|
42
|
+
unmount: () => {
|
|
43
|
+
if (root) {
|
|
44
|
+
root.unmount();
|
|
45
|
+
if (roots.get(node) === root) {
|
|
46
|
+
roots.delete(node);
|
|
47
|
+
}
|
|
48
|
+
root = null;
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=bind.js.map
|
package/dist/bind.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bind.js","sourceRoot":"","sources":["../src/bind.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAEjC,MAAM,CAAC,KAAK,UAAU,2BAA2B;IAC/C,IAAI,CAAC;QACH,aAAa;QACb,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;QACpC,aAAa;QACb,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAClD,OAAO,CAAC,IAAiB,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IACpE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CACX;2DACqD,CACtD,CAAC;QACF,OAAO,CAAC,IAAiB,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAiB;IAC1C,OAAO;QACL,MAAM,EAAE,CAAC,IAAS,EAAE,KAAU,EAAE,QAAgB,EAAE,EAAE,CAClD,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QACxD,MAAM,EAAE,CAAC,OAAY,EAAE,EAAE;YACvB,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC;KACzC,CAAC;AACJ,CAAC;AAED,MAAM,KAAK,GAAG,IAAI,OAAO,EAAoB,CAAC;AAE9C,SAAS,YAAY,CAAC,IAAiB,EAAE,KAAU,EAAE,QAAa;IAChE,IAAI,IAAI,GAAQ,IAAI,CAAC;IACrB,OAAO;QACL,MAAM,EAAE,CAAC,IAAS,EAAE,KAAU,EAAE,QAAgB,EAAE,EAAE,CAClD,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QACvD,MAAM,EAAE,CAAC,OAAY,EAAE,EAAE;YACvB,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBACrB,IAAI,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;oBACjC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBACxB,CAAC;qBAAM,CAAC;oBACN,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACzB,CAAC;YACH,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,EAAE,GAAG,EAAE;YACZ,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;oBAC7B,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACrB,CAAC;gBACD,IAAI,GAAG,IAAI,CAAC;YACd,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ReactPyClientInterface, ReactPyModule, GenericReactPyClientProps, ReactPyUrls } from "./types";
|
|
2
|
+
export declare abstract class BaseReactPyClient implements ReactPyClientInterface {
|
|
3
|
+
private readonly handlers;
|
|
4
|
+
protected readonly ready: Promise<void>;
|
|
5
|
+
private resolveReady;
|
|
6
|
+
constructor();
|
|
7
|
+
onMessage(type: string, handler: (message: any) => void): () => void;
|
|
8
|
+
abstract sendMessage(message: any): void;
|
|
9
|
+
abstract loadModule(moduleName: string): Promise<ReactPyModule>;
|
|
10
|
+
/**
|
|
11
|
+
* Handle an incoming message.
|
|
12
|
+
*
|
|
13
|
+
* This should be called by subclasses when a message is received.
|
|
14
|
+
*
|
|
15
|
+
* @param message The message to handle. The message must have a `type` property.
|
|
16
|
+
*/
|
|
17
|
+
protected handleIncoming(message: any): void;
|
|
18
|
+
}
|
|
19
|
+
export declare class ReactPyClient extends BaseReactPyClient implements ReactPyClientInterface {
|
|
20
|
+
urls: ReactPyUrls;
|
|
21
|
+
socket: {
|
|
22
|
+
current?: WebSocket;
|
|
23
|
+
};
|
|
24
|
+
mountElement: HTMLElement;
|
|
25
|
+
constructor(props: GenericReactPyClientProps);
|
|
26
|
+
sendMessage(message: any): void;
|
|
27
|
+
loadModule(moduleName: string): Promise<ReactPyModule>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,sBAAsB,EACtB,aAAa,EACb,yBAAyB,EACzB,WAAW,EACZ,MAAM,SAAS,CAAC;AAGjB,8BAAsB,iBAAkB,YAAW,sBAAsB;IACvE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqD;IAC9E,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,CAAC,YAAY,CAA6B;;IAOjD,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,GAAG,MAAM,IAAI;IAQpE,QAAQ,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IACxC,QAAQ,CAAC,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAE/D;;;;;;OAMG;IACH,SAAS,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;CAe7C;AAED,qBAAa,aACX,SAAQ,iBACR,YAAW,sBAAsB;IAEjC,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE;QAAE,OAAO,CAAC,EAAE,SAAS,CAAA;KAAE,CAAC;IAChC,YAAY,EAAE,WAAW,CAAC;gBAEd,KAAK,EAAE,yBAAyB;IAa5C,WAAW,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAI/B,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;CAGvD"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import logger from "./logger";
|
|
2
|
+
import { createReconnectingWebSocket } from "./websocket";
|
|
3
|
+
export class BaseReactPyClient {
|
|
4
|
+
handlers = {};
|
|
5
|
+
ready;
|
|
6
|
+
resolveReady;
|
|
7
|
+
constructor() {
|
|
8
|
+
this.resolveReady = () => { };
|
|
9
|
+
this.ready = new Promise((resolve) => (this.resolveReady = resolve));
|
|
10
|
+
}
|
|
11
|
+
onMessage(type, handler) {
|
|
12
|
+
(this.handlers[type] || (this.handlers[type] = [])).push(handler);
|
|
13
|
+
this.resolveReady(undefined);
|
|
14
|
+
return () => {
|
|
15
|
+
this.handlers[type] = this.handlers[type].filter((h) => h !== handler);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Handle an incoming message.
|
|
20
|
+
*
|
|
21
|
+
* This should be called by subclasses when a message is received.
|
|
22
|
+
*
|
|
23
|
+
* @param message The message to handle. The message must have a `type` property.
|
|
24
|
+
*/
|
|
25
|
+
handleIncoming(message) {
|
|
26
|
+
if (!message.type) {
|
|
27
|
+
logger.warn("Received message without type", message);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const messageHandlers = this.handlers[message.type];
|
|
31
|
+
if (!messageHandlers) {
|
|
32
|
+
logger.warn("Received message without handler", message);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
messageHandlers.forEach((h) => h(message));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export class ReactPyClient extends BaseReactPyClient {
|
|
39
|
+
urls;
|
|
40
|
+
socket;
|
|
41
|
+
mountElement;
|
|
42
|
+
constructor(props) {
|
|
43
|
+
super();
|
|
44
|
+
this.urls = props.urls;
|
|
45
|
+
this.mountElement = props.mountElement;
|
|
46
|
+
this.socket = createReconnectingWebSocket({
|
|
47
|
+
url: this.urls.componentUrl,
|
|
48
|
+
readyPromise: this.ready,
|
|
49
|
+
...props.reconnectOptions,
|
|
50
|
+
onMessage: async ({ data }) => this.handleIncoming(JSON.parse(data)),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
sendMessage(message) {
|
|
54
|
+
this.socket.current?.send(JSON.stringify(message));
|
|
55
|
+
}
|
|
56
|
+
loadModule(moduleName) {
|
|
57
|
+
return import(`${this.urls.jsModulesPath}${moduleName}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,UAAU,CAAC;AAO9B,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,OAAgB,iBAAiB;IACpB,QAAQ,GAAkD,EAAE,CAAC;IAC3D,KAAK,CAAgB;IAChC,YAAY,CAA6B;IAEjD;QACE,IAAI,CAAC,YAAY,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,SAAS,CAAC,IAAY,EAAE,OAA+B;QACrD,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClE,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAC7B,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC;QACzE,CAAC,CAAC;IACJ,CAAC;IAKD;;;;;;OAMG;IACO,cAAc,CAAC,OAAY;QACnC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,MAAM,CAAC,IAAI,CAAC,+BAA+B,EAAE,OAAO,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QAED,MAAM,eAAe,GACnB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE,OAAO,CAAC,CAAC;YACzD,OAAO;QACT,CAAC;QAED,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7C,CAAC;CACF;AAED,MAAM,OAAO,aACX,SAAQ,iBAAiB;IAGzB,IAAI,CAAc;IAClB,MAAM,CAA0B;IAChC,YAAY,CAAc;IAE1B,YAAY,KAAgC;QAC1C,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;QACvC,IAAI,CAAC,MAAM,GAAG,2BAA2B,CAAC;YACxC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY;YAC3B,YAAY,EAAE,IAAI,CAAC,KAAK;YACxB,GAAG,KAAK,CAAC,gBAAgB;YACzB,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;SACrE,CAAC,CAAC;IACL,CAAC;IAED,WAAW,CAAC,OAAY;QACtB,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,UAAU,CAAC,UAAkB;QAC3B,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,GAAG,UAAU,EAAE,CAAC,CAAC;IAC3D,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type JSX } from "preact";
|
|
2
|
+
import type { ReactPyVdom } from "./types";
|
|
3
|
+
import type { ReactPyClient } from "./client";
|
|
4
|
+
export declare function Layout(props: {
|
|
5
|
+
client: ReactPyClient;
|
|
6
|
+
}): JSX.Element;
|
|
7
|
+
export declare function Element({ model }: {
|
|
8
|
+
model: ReactPyVdom;
|
|
9
|
+
}): JSX.Element | null;
|
|
10
|
+
//# sourceMappingURL=components.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/components.tsx"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,GAAG,EAET,MAAM,QAAQ,CAAC;AAEhB,OAAO,KAAK,EAGV,WAAW,EACZ,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAI9C,wBAAgB,MAAM,CAAC,KAAK,EAAE;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAsBpE;AAED,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CAoB7E"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { jsx as _jsx } from "preact/jsx-runtime";
|
|
2
|
+
import { set as setJsonPointer } from "json-pointer";
|
|
3
|
+
import { createContext, createElement, Fragment, } from "preact";
|
|
4
|
+
import { useContext, useEffect, useRef, useState } from "preact/hooks";
|
|
5
|
+
import { createAttributes, createChildren, loadImportSource } from "./vdom";
|
|
6
|
+
const ClientContext = createContext(null);
|
|
7
|
+
export function Layout(props) {
|
|
8
|
+
const currentModel = useState({ tagName: "" })[0];
|
|
9
|
+
const forceUpdate = useForceUpdate();
|
|
10
|
+
useEffect(() => props.client.onMessage("layout-update", ({ path, model }) => {
|
|
11
|
+
if (path === "") {
|
|
12
|
+
Object.assign(currentModel, model);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
setJsonPointer(currentModel, path, model);
|
|
16
|
+
}
|
|
17
|
+
forceUpdate();
|
|
18
|
+
}), [currentModel, props.client]);
|
|
19
|
+
return (_jsx(ClientContext.Provider, { value: props.client, children: _jsx(Element, { model: currentModel }) }));
|
|
20
|
+
}
|
|
21
|
+
export function Element({ model }) {
|
|
22
|
+
if (model.error !== undefined) {
|
|
23
|
+
if (model.error) {
|
|
24
|
+
return _jsx("pre", { children: model.error });
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
let SpecializedElement;
|
|
31
|
+
if (model.tagName in SPECIAL_ELEMENTS) {
|
|
32
|
+
SpecializedElement =
|
|
33
|
+
SPECIAL_ELEMENTS[model.tagName];
|
|
34
|
+
}
|
|
35
|
+
else if (model.importSource) {
|
|
36
|
+
SpecializedElement = ImportedElement;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
SpecializedElement = StandardElement;
|
|
40
|
+
}
|
|
41
|
+
return _jsx(SpecializedElement, { model: model });
|
|
42
|
+
}
|
|
43
|
+
function StandardElement({ model }) {
|
|
44
|
+
const client = useContext(ClientContext);
|
|
45
|
+
// Use createElement here to avoid warning about variable numbers of children not
|
|
46
|
+
// having keys. Warning about this must now be the responsibility of the client
|
|
47
|
+
// providing the models instead of the client rendering them.
|
|
48
|
+
return createElement(model.tagName === "" ? Fragment : model.tagName, createAttributes(model, client), ...createChildren(model, (child) => {
|
|
49
|
+
return _jsx(Element, { model: child }, child.attributes?.key);
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
function UserInputElement({ model }) {
|
|
53
|
+
const client = useContext(ClientContext);
|
|
54
|
+
const props = createAttributes(model, client);
|
|
55
|
+
const [value, setValue] = useState(props.value);
|
|
56
|
+
// honor changes to value from the client via props
|
|
57
|
+
useEffect(() => setValue(props.value), [props.value]);
|
|
58
|
+
const givenOnChange = props.onChange;
|
|
59
|
+
if (typeof givenOnChange === "function") {
|
|
60
|
+
props.onChange = (event) => {
|
|
61
|
+
// immediately update the value to give the user feedback
|
|
62
|
+
if (event.target) {
|
|
63
|
+
setValue(event.target.value);
|
|
64
|
+
}
|
|
65
|
+
// allow the client to respond (and possibly change the value)
|
|
66
|
+
givenOnChange(event);
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
// Use createElement here to avoid warning about variable numbers of children not
|
|
70
|
+
// having keys. Warning about this must now be the responsibility of the client
|
|
71
|
+
// providing the models instead of the client rendering them.
|
|
72
|
+
return createElement(model.tagName,
|
|
73
|
+
// overwrite
|
|
74
|
+
{ ...props, value }, ...createChildren(model, (child) => (_jsx(Element, { model: child }, child.attributes?.key))));
|
|
75
|
+
}
|
|
76
|
+
function ScriptElement({ model }) {
|
|
77
|
+
const ref = useRef(null);
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
// Don't run if the parent element is missing
|
|
80
|
+
if (!ref.current) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
// Create the script element
|
|
84
|
+
const scriptElement = document.createElement("script");
|
|
85
|
+
for (const [k, v] of Object.entries(model.attributes || {})) {
|
|
86
|
+
scriptElement.setAttribute(k, v);
|
|
87
|
+
}
|
|
88
|
+
// Add the script content as text
|
|
89
|
+
const scriptContent = model?.children?.filter((value) => typeof value == "string")[0];
|
|
90
|
+
if (scriptContent) {
|
|
91
|
+
scriptElement.appendChild(document.createTextNode(scriptContent));
|
|
92
|
+
}
|
|
93
|
+
// Append the script element to the parent element
|
|
94
|
+
ref.current.appendChild(scriptElement);
|
|
95
|
+
// Remove the script element when the component is unmounted
|
|
96
|
+
return () => {
|
|
97
|
+
ref.current?.removeChild(scriptElement);
|
|
98
|
+
};
|
|
99
|
+
}, [model.attributes?.key]);
|
|
100
|
+
return _jsx("div", { ref: ref });
|
|
101
|
+
}
|
|
102
|
+
function ImportedElement({ model }) {
|
|
103
|
+
const importSourceVdom = model.importSource;
|
|
104
|
+
const importSourceRef = useImportSource(model);
|
|
105
|
+
if (!importSourceVdom) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
const importSourceFallback = importSourceVdom.fallback;
|
|
109
|
+
if (!importSourceVdom) {
|
|
110
|
+
// display a fallback if one was given
|
|
111
|
+
if (!importSourceFallback) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
else if (typeof importSourceFallback === "string") {
|
|
115
|
+
return _jsx("span", { children: importSourceFallback });
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
return _jsx(StandardElement, { model: importSourceFallback });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
return _jsx("span", { ref: importSourceRef });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function useForceUpdate() {
|
|
126
|
+
const [, setState] = useState(false);
|
|
127
|
+
return () => setState((old) => !old);
|
|
128
|
+
}
|
|
129
|
+
function useImportSource(model) {
|
|
130
|
+
const vdomImportSource = model.importSource;
|
|
131
|
+
const vdomImportSourceJsonString = JSON.stringify(vdomImportSource);
|
|
132
|
+
const mountPoint = useRef(null);
|
|
133
|
+
const client = useContext(ClientContext);
|
|
134
|
+
const [binding, setBinding] = useState(null);
|
|
135
|
+
const bindingSource = useRef(null);
|
|
136
|
+
useEffect(() => {
|
|
137
|
+
let unmounted = false;
|
|
138
|
+
let currentBinding = null;
|
|
139
|
+
if (vdomImportSource) {
|
|
140
|
+
loadImportSource(vdomImportSource, client).then((bind) => {
|
|
141
|
+
if (!unmounted && mountPoint.current) {
|
|
142
|
+
currentBinding = bind(mountPoint.current);
|
|
143
|
+
bindingSource.current = vdomImportSourceJsonString;
|
|
144
|
+
setBinding(currentBinding);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
return () => {
|
|
149
|
+
unmounted = true;
|
|
150
|
+
if (currentBinding &&
|
|
151
|
+
vdomImportSource &&
|
|
152
|
+
!vdomImportSource.unmountBeforeUpdate) {
|
|
153
|
+
currentBinding.unmount();
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}, [client, vdomImportSourceJsonString, setBinding, mountPoint.current]);
|
|
157
|
+
// this effect must run every time in case the model has changed
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
if (!(binding && vdomImportSource)) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (bindingSource.current !== vdomImportSourceJsonString) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
binding.render(model);
|
|
166
|
+
if (vdomImportSource.unmountBeforeUpdate) {
|
|
167
|
+
return binding.unmount;
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
return mountPoint;
|
|
171
|
+
}
|
|
172
|
+
const SPECIAL_ELEMENTS = {
|
|
173
|
+
input: UserInputElement,
|
|
174
|
+
script: ScriptElement,
|
|
175
|
+
select: UserInputElement,
|
|
176
|
+
textarea: UserInputElement,
|
|
177
|
+
};
|
|
178
|
+
//# sourceMappingURL=components.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.js","sourceRoot":"","sources":["../src/components.tsx"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from "./client";
|
|
2
|
+
export * from "./components";
|
|
3
|
+
export * from "./mount";
|
|
4
|
+
export * from "./types";
|
|
5
|
+
export * from "./vdom";
|
|
6
|
+
export * from "./websocket";
|
|
7
|
+
export { default as React } from "preact/compat";
|
|
8
|
+
export { default as ReactDOM } from "preact/compat";
|
|
9
|
+
export { jsx, jsxs, Fragment } from "preact/jsx-runtime";
|
|
10
|
+
export * as preact from "preact";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC"}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";mBACiB,GAAG,EAAE,KAAG,IAAI;oBACX,GAAG,EAAE,KAAG,IAAI;oBACZ,GAAG,EAAE,KAAG,IAAI;qBACX,GAAG,EAAE,KAAG,IAAI;;AAJ/B,wBAKE"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
log: (...args) => console.log("[ReactPy]", ...args),
|
|
3
|
+
info: (...args) => console.info("[ReactPy]", ...args),
|
|
4
|
+
warn: (...args) => console.warn("[ReactPy]", ...args),
|
|
5
|
+
error: (...args) => console.error("[ReactPy]", ...args),
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,eAAe;IACb,GAAG,EAAE,CAAC,GAAG,IAAW,EAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC;IAChE,IAAI,EAAE,CAAC,GAAG,IAAW,EAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC;IAClE,IAAI,EAAE,CAAC,GAAG,IAAW,EAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC;IAClE,KAAK,EAAE,CAAC,GAAG,IAAW,EAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC;CACrE,CAAC"}
|
package/dist/mount.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../src/mount.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,QAkC7C"}
|
package/dist/mount.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx } from "preact/jsx-runtime";
|
|
2
|
+
import { render } from "preact";
|
|
3
|
+
import { ReactPyClient } from "./client";
|
|
4
|
+
import { Layout } from "./components";
|
|
5
|
+
export function mountReactPy(props) {
|
|
6
|
+
// WebSocket route for component rendering
|
|
7
|
+
const wsProtocol = `ws${window.location.protocol === "https:" ? "s" : ""}:`;
|
|
8
|
+
const wsOrigin = `${wsProtocol}//${window.location.host}`;
|
|
9
|
+
const componentUrl = new URL(`${wsOrigin}${props.pathPrefix}${props.componentPath || ""}`);
|
|
10
|
+
// Embed the initial HTTP path into the WebSocket URL
|
|
11
|
+
componentUrl.searchParams.append("http_pathname", window.location.pathname);
|
|
12
|
+
if (window.location.search) {
|
|
13
|
+
componentUrl.searchParams.append("http_query_string", window.location.search);
|
|
14
|
+
}
|
|
15
|
+
// Configure a new ReactPy client
|
|
16
|
+
const client = new ReactPyClient({
|
|
17
|
+
urls: {
|
|
18
|
+
componentUrl: componentUrl,
|
|
19
|
+
jsModulesPath: `${window.location.origin}${props.pathPrefix}modules/`,
|
|
20
|
+
},
|
|
21
|
+
reconnectOptions: {
|
|
22
|
+
interval: props.reconnectInterval || 750,
|
|
23
|
+
maxInterval: props.reconnectMaxInterval || 60000,
|
|
24
|
+
maxRetries: props.reconnectMaxRetries || 150,
|
|
25
|
+
backoffMultiplier: props.reconnectBackoffMultiplier || 1.25,
|
|
26
|
+
},
|
|
27
|
+
mountElement: props.mountElement,
|
|
28
|
+
});
|
|
29
|
+
// Start rendering the component
|
|
30
|
+
render(_jsx(Layout, { client: client }), props.mountElement);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=mount.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mount.js","sourceRoot":"","sources":["../src/mount.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAGtC,MAAM,UAAU,YAAY,CAAC,KAAiB;IAC5C,0CAA0C;IAC1C,MAAM,UAAU,GAAG,KAAK,MAAM,CAAC,QAAQ,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC;IAC5E,MAAM,QAAQ,GAAG,GAAG,UAAU,KAAK,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC1D,MAAM,YAAY,GAAG,IAAI,GAAG,CAC1B,GAAG,QAAQ,GAAG,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,aAAa,IAAI,EAAE,EAAE,CAC7D,CAAC;IAEF,qDAAqD;IACrD,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC5E,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC3B,YAAY,CAAC,YAAY,CAAC,MAAM,CAC9B,mBAAmB,EACnB,MAAM,CAAC,QAAQ,CAAC,MAAM,CACvB,CAAC;IACJ,CAAC;IAED,iCAAiC;IACjC,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC;QAC/B,IAAI,EAAE;YACJ,YAAY,EAAE,YAAY;YAC1B,aAAa,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC,UAAU,UAAU;SACtE;QACD,gBAAgB,EAAE;YAChB,QAAQ,EAAE,KAAK,CAAC,iBAAiB,IAAI,GAAG;YACxC,WAAW,EAAE,KAAK,CAAC,oBAAoB,IAAI,KAAK;YAChD,UAAU,EAAE,KAAK,CAAC,mBAAmB,IAAI,GAAG;YAC5C,iBAAiB,EAAE,KAAK,CAAC,0BAA0B,IAAI,IAAI;SAC5D;QACD,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC,CAAC;IAEH,gCAAgC;IAChC,MAAM,CAAC,KAAC,MAAM,IAAC,MAAM,EAAE,MAAM,GAAI,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;AACzD,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type { ComponentType } from "preact";
|
|
2
|
+
export type ReconnectOptions = {
|
|
3
|
+
interval: number;
|
|
4
|
+
maxInterval: number;
|
|
5
|
+
maxRetries: number;
|
|
6
|
+
backoffMultiplier: number;
|
|
7
|
+
};
|
|
8
|
+
export type CreateReconnectingWebSocketProps = {
|
|
9
|
+
url: URL;
|
|
10
|
+
readyPromise: Promise<void>;
|
|
11
|
+
onMessage: (message: MessageEvent<any>) => void;
|
|
12
|
+
onOpen?: () => void;
|
|
13
|
+
onClose?: () => void;
|
|
14
|
+
interval: number;
|
|
15
|
+
maxInterval: number;
|
|
16
|
+
maxRetries: number;
|
|
17
|
+
backoffMultiplier: number;
|
|
18
|
+
};
|
|
19
|
+
export type ReactPyUrls = {
|
|
20
|
+
componentUrl: URL;
|
|
21
|
+
jsModulesPath: string;
|
|
22
|
+
};
|
|
23
|
+
export type GenericReactPyClientProps = {
|
|
24
|
+
urls: ReactPyUrls;
|
|
25
|
+
reconnectOptions: ReconnectOptions;
|
|
26
|
+
mountElement: HTMLElement;
|
|
27
|
+
};
|
|
28
|
+
export type MountProps = {
|
|
29
|
+
mountElement: HTMLElement;
|
|
30
|
+
pathPrefix: string;
|
|
31
|
+
componentPath?: string;
|
|
32
|
+
reconnectInterval?: number;
|
|
33
|
+
reconnectMaxInterval?: number;
|
|
34
|
+
reconnectMaxRetries?: number;
|
|
35
|
+
reconnectBackoffMultiplier?: number;
|
|
36
|
+
};
|
|
37
|
+
export type ReactPyComponent = ComponentType<{
|
|
38
|
+
model: ReactPyVdom;
|
|
39
|
+
}>;
|
|
40
|
+
export type ReactPyVdom = {
|
|
41
|
+
tagName: string;
|
|
42
|
+
attributes?: {
|
|
43
|
+
[key: string]: string;
|
|
44
|
+
};
|
|
45
|
+
children?: (ReactPyVdom | string)[];
|
|
46
|
+
error?: string;
|
|
47
|
+
eventHandlers?: {
|
|
48
|
+
[key: string]: ReactPyVdomEventHandler;
|
|
49
|
+
};
|
|
50
|
+
inlineJavaScript?: {
|
|
51
|
+
[key: string]: string;
|
|
52
|
+
};
|
|
53
|
+
importSource?: ReactPyVdomImportSource;
|
|
54
|
+
};
|
|
55
|
+
export type ReactPyVdomEventHandler = {
|
|
56
|
+
target: string;
|
|
57
|
+
preventDefault?: boolean;
|
|
58
|
+
stopPropagation?: boolean;
|
|
59
|
+
};
|
|
60
|
+
export type ReactPyVdomImportSource = {
|
|
61
|
+
source: string;
|
|
62
|
+
sourceType?: "URL" | "NAME";
|
|
63
|
+
fallback?: string | ReactPyVdom;
|
|
64
|
+
unmountBeforeUpdate?: boolean;
|
|
65
|
+
};
|
|
66
|
+
export type ReactPyModule = {
|
|
67
|
+
bind: (node: HTMLElement, context: ReactPyModuleBindingContext) => ReactPyModuleBinding;
|
|
68
|
+
} & {
|
|
69
|
+
[key: string]: any;
|
|
70
|
+
};
|
|
71
|
+
export type ReactPyModuleBindingContext = {
|
|
72
|
+
sendMessage: ReactPyClientInterface["sendMessage"];
|
|
73
|
+
onMessage: ReactPyClientInterface["onMessage"];
|
|
74
|
+
};
|
|
75
|
+
export type ReactPyModuleBinding = {
|
|
76
|
+
create: (type: any, props?: any, children?: (any | string | ReactPyVdom)[]) => any;
|
|
77
|
+
render: (element: any) => void;
|
|
78
|
+
unmount: () => void;
|
|
79
|
+
};
|
|
80
|
+
export type BindImportSource = (node: HTMLElement) => ImportSourceBinding | null;
|
|
81
|
+
export type ImportSourceBinding = {
|
|
82
|
+
render: (model: ReactPyVdom) => void;
|
|
83
|
+
unmount: () => void;
|
|
84
|
+
};
|
|
85
|
+
export type LayoutUpdateMessage = {
|
|
86
|
+
type: "layout-update";
|
|
87
|
+
path: string;
|
|
88
|
+
model: ReactPyVdom;
|
|
89
|
+
};
|
|
90
|
+
export type LayoutEventMessage = {
|
|
91
|
+
type: "layout-event";
|
|
92
|
+
target: string;
|
|
93
|
+
data: any;
|
|
94
|
+
};
|
|
95
|
+
export type IncomingMessage = LayoutUpdateMessage;
|
|
96
|
+
export type OutgoingMessage = LayoutEventMessage;
|
|
97
|
+
export type Message = IncomingMessage | OutgoingMessage;
|
|
98
|
+
/**
|
|
99
|
+
* A client for communicating with a ReactPy server.
|
|
100
|
+
*/
|
|
101
|
+
export interface ReactPyClientInterface {
|
|
102
|
+
/**
|
|
103
|
+
* Register a handler for a message type.
|
|
104
|
+
*
|
|
105
|
+
* The first time this is called, the client will be considered ready.
|
|
106
|
+
*
|
|
107
|
+
* @param type The type of message to handle.
|
|
108
|
+
* @param handler The handler to call when a message of the given type is received.
|
|
109
|
+
* @returns A function to unregister the handler.
|
|
110
|
+
*/
|
|
111
|
+
onMessage(type: string, handler: (message: any) => void): () => void;
|
|
112
|
+
/**
|
|
113
|
+
* Send a message to the server.
|
|
114
|
+
*
|
|
115
|
+
* @param message The message to send. Messages must have a `type` property.
|
|
116
|
+
*/
|
|
117
|
+
sendMessage(message: any): void;
|
|
118
|
+
/**
|
|
119
|
+
* Load a module from the server.
|
|
120
|
+
* @param moduleName The name of the module to load.
|
|
121
|
+
* @returns A promise that resolves to the module.
|
|
122
|
+
*/
|
|
123
|
+
loadModule(moduleName: string): Promise<ReactPyModule>;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/dist/vdom.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ReactPyVdom, ReactPyVdomImportSource, BindImportSource } from "./types";
|
|
2
|
+
import type { ReactPyClient } from "./client";
|
|
3
|
+
export declare function loadImportSource(vdomImportSource: ReactPyVdomImportSource, client: ReactPyClient): Promise<BindImportSource>;
|
|
4
|
+
export declare function createChildren<Child>(model: ReactPyVdom, createChild: (child: ReactPyVdom) => Child): (Child | string)[];
|
|
5
|
+
export declare function createAttributes(model: ReactPyVdom, client: ReactPyClient): {
|
|
6
|
+
[key: string]: any;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=vdom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vdom.d.ts","sourceRoot":"","sources":["../src/vdom.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,uBAAuB,EAGvB,gBAAgB,EAGjB,MAAM,SAAS,CAAC;AAGjB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAsB,gBAAgB,CACpC,gBAAgB,EAAE,uBAAuB,EACzC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,gBAAgB,CAAC,CA2C3B;AAsGD,wBAAgB,cAAc,CAAC,KAAK,EAClC,KAAK,EAAE,WAAW,EAClB,WAAW,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,KAAK,GACzC,CAAC,KAAK,GAAG,MAAM,CAAC,EAAE,CAapB;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,aAAa,GACpB;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,CAmBxB"}
|
package/dist/vdom.js
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import eventToObject from "event-to-object";
|
|
2
|
+
import { Fragment } from "preact";
|
|
3
|
+
import { infer_bind_from_environment } from "./bind";
|
|
4
|
+
import log from "./logger";
|
|
5
|
+
export async function loadImportSource(vdomImportSource, client) {
|
|
6
|
+
let module;
|
|
7
|
+
if (vdomImportSource.sourceType === "URL") {
|
|
8
|
+
module = await import(vdomImportSource.source);
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
module = await client.loadModule(vdomImportSource.source);
|
|
12
|
+
}
|
|
13
|
+
let { bind } = module;
|
|
14
|
+
if (typeof bind !== "function") {
|
|
15
|
+
bind = await infer_bind_from_environment();
|
|
16
|
+
}
|
|
17
|
+
return (node) => {
|
|
18
|
+
const binding = bind(node, {
|
|
19
|
+
sendMessage: client.sendMessage,
|
|
20
|
+
onMessage: client.onMessage,
|
|
21
|
+
});
|
|
22
|
+
if (!(typeof binding.create === "function" &&
|
|
23
|
+
typeof binding.render === "function" &&
|
|
24
|
+
typeof binding.unmount === "function")) {
|
|
25
|
+
log.error(`${vdomImportSource.source} returned an impropper binding`);
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
render: (model) => binding.render(createImportSourceElement({
|
|
30
|
+
client,
|
|
31
|
+
module,
|
|
32
|
+
binding,
|
|
33
|
+
model,
|
|
34
|
+
currentImportSource: vdomImportSource,
|
|
35
|
+
})),
|
|
36
|
+
unmount: binding.unmount,
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function createImportSourceElement(props) {
|
|
41
|
+
let type;
|
|
42
|
+
if (props.model.importSource) {
|
|
43
|
+
if (!isImportSourceEqual(props.currentImportSource, props.model.importSource)) {
|
|
44
|
+
return props.binding.create("reactpy-child", {
|
|
45
|
+
ref: (node) => {
|
|
46
|
+
if (node) {
|
|
47
|
+
node.client = props.client;
|
|
48
|
+
node.model = props.model;
|
|
49
|
+
node.requestUpdate();
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
type = getComponentFromModule(props.module, props.model.tagName, props.model.importSource);
|
|
56
|
+
if (!type) {
|
|
57
|
+
// Error message logged within getComponentFromModule
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
type = props.model.tagName === "" ? Fragment : props.model.tagName;
|
|
64
|
+
}
|
|
65
|
+
return props.binding.create(type, createAttributes(props.model, props.client), createChildren(props.model, (child) => createImportSourceElement({
|
|
66
|
+
...props,
|
|
67
|
+
model: child,
|
|
68
|
+
})));
|
|
69
|
+
}
|
|
70
|
+
function getComponentFromModule(module, componentName, importSource) {
|
|
71
|
+
/* Gets the component with the provided name from the provided module.
|
|
72
|
+
|
|
73
|
+
Built specifically to work on inifinitely deep nested components.
|
|
74
|
+
For example, component "My.Nested.Component" is accessed from
|
|
75
|
+
ModuleA like so: ModuleA["My"]["Nested"]["Component"].
|
|
76
|
+
*/
|
|
77
|
+
const componentParts = componentName.split(".");
|
|
78
|
+
let Component = null;
|
|
79
|
+
for (let i = 0; i < componentParts.length; i++) {
|
|
80
|
+
const iterAttr = componentParts[i];
|
|
81
|
+
Component = i == 0 ? module[iterAttr] : Component[iterAttr];
|
|
82
|
+
if (!Component) {
|
|
83
|
+
if (i == 0) {
|
|
84
|
+
log.error("Module from source " +
|
|
85
|
+
stringifyImportSource(importSource) +
|
|
86
|
+
` does not export ${iterAttr}`);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
console.error(`Component ${componentParts.slice(0, i).join(".")} from source ` +
|
|
90
|
+
stringifyImportSource(importSource) +
|
|
91
|
+
` does not have subcomponent ${iterAttr}`);
|
|
92
|
+
}
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return Component;
|
|
97
|
+
}
|
|
98
|
+
function isImportSourceEqual(source1, source2) {
|
|
99
|
+
return (source1.source === source2.source &&
|
|
100
|
+
source1.sourceType === source2.sourceType);
|
|
101
|
+
}
|
|
102
|
+
function stringifyImportSource(importSource) {
|
|
103
|
+
return JSON.stringify({
|
|
104
|
+
source: importSource.source,
|
|
105
|
+
sourceType: importSource.sourceType,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
export function createChildren(model, createChild) {
|
|
109
|
+
if (!model.children) {
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
return model.children.map((child) => {
|
|
114
|
+
switch (typeof child) {
|
|
115
|
+
case "object":
|
|
116
|
+
return createChild(child);
|
|
117
|
+
case "string":
|
|
118
|
+
return child;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
export function createAttributes(model, client) {
|
|
124
|
+
return Object.fromEntries(Object.entries({
|
|
125
|
+
// Normal HTML attributes
|
|
126
|
+
...model.attributes,
|
|
127
|
+
// Construct event handlers
|
|
128
|
+
...Object.fromEntries(Object.entries(model.eventHandlers || {}).map(([name, handler]) => createEventHandler(client, name, handler))),
|
|
129
|
+
...Object.fromEntries(Object.entries(model.inlineJavaScript || {}).map(([name, inlineJavaScript]) => createInlineJavaScript(name, inlineJavaScript))),
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
function createEventHandler(client, name, { target, preventDefault, stopPropagation }) {
|
|
133
|
+
const eventHandler = function (...args) {
|
|
134
|
+
const data = Array.from(args).map((value) => {
|
|
135
|
+
const event = value;
|
|
136
|
+
if (preventDefault) {
|
|
137
|
+
event.preventDefault();
|
|
138
|
+
}
|
|
139
|
+
if (stopPropagation) {
|
|
140
|
+
event.stopPropagation();
|
|
141
|
+
}
|
|
142
|
+
// Convert JavaScript objects to plain JSON, if needed
|
|
143
|
+
if (typeof event === "object") {
|
|
144
|
+
return eventToObject(event);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
return event;
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
client.sendMessage({ type: "layout-event", data, target });
|
|
151
|
+
};
|
|
152
|
+
eventHandler.isHandler = true;
|
|
153
|
+
return [name, eventHandler];
|
|
154
|
+
}
|
|
155
|
+
function createInlineJavaScript(name, inlineJavaScript) {
|
|
156
|
+
/* Function that will execute the string-like InlineJavaScript
|
|
157
|
+
via eval in the most appropriate way */
|
|
158
|
+
const wrappedExecutable = function (...args) {
|
|
159
|
+
function handleExecution(...args) {
|
|
160
|
+
const evalResult = eval(inlineJavaScript);
|
|
161
|
+
if (typeof evalResult == "function") {
|
|
162
|
+
return evalResult(...args);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (args.length > 0 && args[0] instanceof Event) {
|
|
166
|
+
/* If being triggered by an event, set the event's current
|
|
167
|
+
target to "this". This ensures that inline
|
|
168
|
+
javascript statements such as the following work:
|
|
169
|
+
html.button({"onclick": 'this.value = "Clicked!"'}, "Click Me")*/
|
|
170
|
+
return handleExecution.call(args[0].currentTarget, ...args);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
/* If not being triggered by an event, do not set "this" and
|
|
174
|
+
just call normally */
|
|
175
|
+
return handleExecution(...args);
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
wrappedExecutable.isHandler = false;
|
|
179
|
+
return [name, wrappedExecutable];
|
|
180
|
+
}
|
|
181
|
+
class ReactPyChild extends HTMLElement {
|
|
182
|
+
mountPoint;
|
|
183
|
+
binding = null;
|
|
184
|
+
_client = null;
|
|
185
|
+
_model = null;
|
|
186
|
+
currentImportSource = null;
|
|
187
|
+
constructor() {
|
|
188
|
+
super();
|
|
189
|
+
this.mountPoint = document.createElement("div");
|
|
190
|
+
this.mountPoint.style.display = "contents";
|
|
191
|
+
}
|
|
192
|
+
connectedCallback() {
|
|
193
|
+
this.appendChild(this.mountPoint);
|
|
194
|
+
}
|
|
195
|
+
set client(value) {
|
|
196
|
+
this._client = value;
|
|
197
|
+
}
|
|
198
|
+
set model(value) {
|
|
199
|
+
this._model = value;
|
|
200
|
+
}
|
|
201
|
+
requestUpdate() {
|
|
202
|
+
this.update();
|
|
203
|
+
}
|
|
204
|
+
async update() {
|
|
205
|
+
if (!this._client || !this._model || !this._model.importSource) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const newImportSource = this._model.importSource;
|
|
209
|
+
if (!this.binding ||
|
|
210
|
+
!this.currentImportSource ||
|
|
211
|
+
!isImportSourceEqual(this.currentImportSource, newImportSource)) {
|
|
212
|
+
if (this.binding) {
|
|
213
|
+
this.binding.unmount();
|
|
214
|
+
this.binding = null;
|
|
215
|
+
}
|
|
216
|
+
this.currentImportSource = newImportSource;
|
|
217
|
+
try {
|
|
218
|
+
const bind = await loadImportSource(newImportSource, this._client);
|
|
219
|
+
if (this.isConnected &&
|
|
220
|
+
this.currentImportSource &&
|
|
221
|
+
isImportSourceEqual(this.currentImportSource, newImportSource)) {
|
|
222
|
+
const oldBinding = this.binding;
|
|
223
|
+
if (oldBinding) {
|
|
224
|
+
oldBinding.unmount();
|
|
225
|
+
}
|
|
226
|
+
this.binding = bind(this.mountPoint);
|
|
227
|
+
if (this.binding) {
|
|
228
|
+
this.binding.render(this._model);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
console.error("Failed to load import source", error);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
if (this.binding) {
|
|
238
|
+
this.binding.render(this._model);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
disconnectedCallback() {
|
|
243
|
+
if (this.binding) {
|
|
244
|
+
this.binding.unmount();
|
|
245
|
+
this.binding = null;
|
|
246
|
+
this.currentImportSource = null;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (typeof customElements !== "undefined" &&
|
|
251
|
+
!customElements.get("reactpy-child")) {
|
|
252
|
+
customElements.define("reactpy-child", ReactPyChild);
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=vdom.js.map
|
package/dist/vdom.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vdom.js","sourceRoot":"","sources":["../src/vdom.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { CreateReconnectingWebSocketProps } from "./types";
|
|
2
|
+
export declare function createReconnectingWebSocket(props: CreateReconnectingWebSocketProps): {
|
|
3
|
+
current?: WebSocket;
|
|
4
|
+
};
|
|
5
|
+
export declare function nextInterval(currentInterval: number, backoffMultiplier: number, maxInterval: number): number;
|
|
6
|
+
//# sourceMappingURL=websocket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,SAAS,CAAC;AAGhE,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,gCAAgC;cAOb,SAAS;EAkDpC;AAED,wBAAgB,YAAY,CAC1B,eAAe,EAAE,MAAM,EACvB,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,GAClB,MAAM,CAOR"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import log from "./logger";
|
|
2
|
+
export function createReconnectingWebSocket(props) {
|
|
3
|
+
const { interval, maxInterval, maxRetries, backoffMultiplier } = props;
|
|
4
|
+
let retries = 0;
|
|
5
|
+
let currentInterval = interval;
|
|
6
|
+
let everConnected = false;
|
|
7
|
+
const closed = false;
|
|
8
|
+
const socket = {};
|
|
9
|
+
const connect = () => {
|
|
10
|
+
if (closed) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
socket.current = new WebSocket(props.url);
|
|
14
|
+
socket.current.onopen = () => {
|
|
15
|
+
everConnected = true;
|
|
16
|
+
log.info("Connected!");
|
|
17
|
+
currentInterval = interval;
|
|
18
|
+
retries = 0;
|
|
19
|
+
if (props.onOpen) {
|
|
20
|
+
props.onOpen();
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
socket.current.onmessage = (event) => {
|
|
24
|
+
if (props.onMessage) {
|
|
25
|
+
props.onMessage(event);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
socket.current.onclose = () => {
|
|
29
|
+
if (props.onClose) {
|
|
30
|
+
props.onClose();
|
|
31
|
+
}
|
|
32
|
+
if (!everConnected) {
|
|
33
|
+
log.info("Failed to connect!");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
log.info("Disconnected!");
|
|
37
|
+
if (retries >= maxRetries) {
|
|
38
|
+
log.info("Connection max retries exhausted!");
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
log.info(`Reconnecting in ${(currentInterval / 1000).toPrecision(4)} seconds...`);
|
|
42
|
+
setTimeout(connect, currentInterval);
|
|
43
|
+
currentInterval = nextInterval(currentInterval, backoffMultiplier, maxInterval);
|
|
44
|
+
retries++;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
props.readyPromise.then(() => log.info("Starting client...")).then(connect);
|
|
48
|
+
return socket;
|
|
49
|
+
}
|
|
50
|
+
export function nextInterval(currentInterval, backoffMultiplier, maxInterval) {
|
|
51
|
+
return Math.min(
|
|
52
|
+
// increase interval by backoff multiplier
|
|
53
|
+
currentInterval * backoffMultiplier,
|
|
54
|
+
// don't exceed max interval
|
|
55
|
+
maxInterval);
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=websocket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"AACA,OAAO,GAAG,MAAM,UAAU,CAAC;AAE3B,MAAM,UAAU,2BAA2B,CACzC,KAAuC;IAEvC,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,iBAAiB,EAAE,GAAG,KAAK,CAAC;IACvE,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,eAAe,GAAG,QAAQ,CAAC;IAC/B,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,MAAM,MAAM,GAAG,KAAK,CAAC;IACrB,MAAM,MAAM,GAA4B,EAAE,CAAC;IAE3C,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,IAAI,MAAM,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QACD,MAAM,CAAC,OAAO,GAAG,IAAI,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE;YAC3B,aAAa,GAAG,IAAI,CAAC;YACrB,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACvB,eAAe,GAAG,QAAQ,CAAC;YAC3B,OAAO,GAAG,CAAC,CAAC;YACZ,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBACjB,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,CAAC;QACH,CAAC,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC,KAAK,EAAE,EAAE;YACnC,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBACpB,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACzB,CAAC;QACH,CAAC,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,OAAO,GAAG,GAAG,EAAE;YAC5B,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAClB,KAAK,CAAC,OAAO,EAAE,CAAC;YAClB,CAAC;YACD,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,GAAG,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;gBAC/B,OAAO;YACT,CAAC;YACD,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAC1B,IAAI,OAAO,IAAI,UAAU,EAAE,CAAC;gBAC1B,GAAG,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;gBAC9C,OAAO;YACT,CAAC;YACD,GAAG,CAAC,IAAI,CACN,mBAAmB,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CACxE,CAAC;YACF,UAAU,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;YACrC,eAAe,GAAG,YAAY,CAC5B,eAAe,EACf,iBAAiB,EACjB,WAAW,CACZ,CAAC;YACF,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;IACJ,CAAC,CAAC;IAEF,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAE5E,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,eAAuB,EACvB,iBAAyB,EACzB,WAAmB;IAEnB,OAAO,IAAI,CAAC,GAAG;IACb,0CAA0C;IAC1C,eAAe,GAAG,iBAAiB;IACnC,4BAA4B;IAC5B,WAAW,CACZ,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -4,14 +4,19 @@
|
|
|
4
4
|
"Ryan Morshead"
|
|
5
5
|
],
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"json-pointer": "
|
|
8
|
-
"preact": "
|
|
9
|
-
"event-to-object": "
|
|
7
|
+
"json-pointer": "^0.6.2",
|
|
8
|
+
"preact": "^10.27.2",
|
|
9
|
+
"event-to-object": "2.0.0"
|
|
10
10
|
},
|
|
11
11
|
"description": "A client for ReactPy implemented in React",
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"src",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
12
17
|
"devDependencies": {
|
|
13
|
-
"@types/json-pointer": "
|
|
14
|
-
"typescript": "
|
|
18
|
+
"@types/json-pointer": "^1.0.34",
|
|
19
|
+
"typescript": "^5.9.3"
|
|
15
20
|
},
|
|
16
21
|
"keywords": [
|
|
17
22
|
"react",
|
|
@@ -31,5 +36,5 @@
|
|
|
31
36
|
"checkTypes": "tsc --noEmit"
|
|
32
37
|
},
|
|
33
38
|
"type": "module",
|
|
34
|
-
"version": "1.0.
|
|
39
|
+
"version": "1.0.3"
|
|
35
40
|
}
|
package/tsconfig.json
DELETED