@reactpy/client 0.2.1 → 0.3.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/dist/components.d.ts.map +1 -1
- package/dist/components.js +11 -14
- package/dist/components.js.map +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.js +1 -0
- package/dist/logger.js.map +1 -0
- package/dist/messages.d.ts +1 -10
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +1 -0
- package/dist/messages.js.map +1 -0
- package/dist/mount.js +1 -0
- package/dist/mount.js.map +1 -0
- package/dist/reactpy-client.d.ts +32 -24
- package/dist/reactpy-client.d.ts.map +1 -1
- package/dist/reactpy-client.js +49 -54
- package/dist/reactpy-client.js.map +1 -0
- package/dist/reactpy-vdom.js +3 -2
- package/dist/reactpy-vdom.js.map +1 -0
- package/package.json +1 -4
- package/src/components.tsx +7 -11
- package/src/messages.ts +1 -16
- package/src/reactpy-client.ts +80 -90
- package/src/reactpy-vdom.tsx +2 -2
package/dist/components.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/components.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/components.tsx"],"names":[],"mappings":";AAaA,OAAO,EACL,WAAW,EAMZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAIjD,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"}
|
package/dist/components.js
CHANGED
|
@@ -6,19 +6,15 @@ const ClientContext = createContext(null);
|
|
|
6
6
|
export function Layout(props) {
|
|
7
7
|
const currentModel = useState({ tagName: "" })[0];
|
|
8
8
|
const forceUpdate = useForceUpdate();
|
|
9
|
-
useEffect(() => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
});
|
|
19
|
-
props.client.start();
|
|
20
|
-
return () => props.client.stop();
|
|
21
|
-
}, [currentModel, props.client]);
|
|
9
|
+
useEffect(() => props.client.onMessage("layout-update", ({ path, model }) => {
|
|
10
|
+
if (path === "") {
|
|
11
|
+
Object.assign(currentModel, model);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
setJsonPointer(currentModel, path, model);
|
|
15
|
+
}
|
|
16
|
+
forceUpdate();
|
|
17
|
+
}), [currentModel, props.client]);
|
|
22
18
|
return (React.createElement(ClientContext.Provider, { value: props.client },
|
|
23
19
|
React.createElement(Element, { model: currentModel })));
|
|
24
20
|
}
|
|
@@ -94,7 +90,7 @@ function ScriptElement({ model }) {
|
|
|
94
90
|
ref.current.appendChild(scriptElement);
|
|
95
91
|
}
|
|
96
92
|
else if (scriptContent) {
|
|
97
|
-
|
|
93
|
+
const scriptResult = eval(scriptContent);
|
|
98
94
|
if (typeof scriptResult == "function") {
|
|
99
95
|
return scriptResult();
|
|
100
96
|
}
|
|
@@ -170,3 +166,4 @@ const SPECIAL_ELEMENTS = {
|
|
|
170
166
|
select: UserInputElement,
|
|
171
167
|
textarea: UserInputElement,
|
|
172
168
|
};
|
|
169
|
+
//# 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.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC"}
|
package/dist/logger.js
CHANGED
|
@@ -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,KAAK,EAAE,CAAC,GAAG,IAAW,EAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC;CACrE,CAAC"}
|
package/dist/messages.d.ts
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
import { ReactPyVdom } from "./reactpy-vdom";
|
|
2
|
-
export interface IMessage {
|
|
3
|
-
type: string;
|
|
4
|
-
}
|
|
5
|
-
export type ConnectionOpenMessage = {
|
|
6
|
-
type: "connection-open";
|
|
7
|
-
};
|
|
8
|
-
export type ConnectionCloseMessage = {
|
|
9
|
-
type: "connection-close";
|
|
10
|
-
};
|
|
11
2
|
export type LayoutUpdateMessage = {
|
|
12
3
|
type: "layout-update";
|
|
13
4
|
path: string;
|
|
@@ -18,7 +9,7 @@ export type LayoutEventMessage = {
|
|
|
18
9
|
target: string;
|
|
19
10
|
data: any;
|
|
20
11
|
};
|
|
21
|
-
export type IncomingMessage = LayoutUpdateMessage
|
|
12
|
+
export type IncomingMessage = LayoutUpdateMessage;
|
|
22
13
|
export type OutgoingMessage = LayoutEventMessage;
|
|
23
14
|
export type Message = IncomingMessage | OutgoingMessage;
|
|
24
15
|
//# sourceMappingURL=messages.d.ts.map
|
package/dist/messages.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,WAAW,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,GAAG,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAClD,MAAM,MAAM,eAAe,GAAG,kBAAkB,CAAC;AACjD,MAAM,MAAM,OAAO,GAAG,eAAe,GAAG,eAAe,CAAC"}
|
package/dist/messages.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":""}
|
package/dist/mount.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mount.js","sourceRoot":"","sources":["../src/mount.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAGtC,MAAM,UAAU,KAAK,CAAC,OAAoB,EAAE,MAAqB;IAC/D,MAAM,CAAC,oBAAC,MAAM,IAAC,MAAM,EAAE,MAAM,GAAI,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC"}
|
package/dist/reactpy-client.d.ts
CHANGED
|
@@ -1,32 +1,47 @@
|
|
|
1
|
-
import { OutgoingMessage, IncomingMessage } from "./messages";
|
|
2
1
|
import { ReactPyModule } from "./reactpy-vdom";
|
|
3
2
|
/**
|
|
4
3
|
* A client for communicating with a ReactPy server.
|
|
5
4
|
*/
|
|
6
5
|
export interface ReactPyClient {
|
|
7
6
|
/**
|
|
8
|
-
*
|
|
7
|
+
* Register a handler for a message type.
|
|
9
8
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* Disconnect from the server and stop receiving messages.
|
|
9
|
+
* The first time this is called, the client will be considered ready.
|
|
10
|
+
*
|
|
11
|
+
* @param type The type of message to handle.
|
|
12
|
+
* @param handler The handler to call when a message of the given type is received.
|
|
13
|
+
* @returns A function to unregister the handler.
|
|
16
14
|
*/
|
|
17
|
-
|
|
15
|
+
onMessage(type: string, handler: (message: any) => void): () => void;
|
|
18
16
|
/**
|
|
19
|
-
*
|
|
17
|
+
* Send a message to the server.
|
|
18
|
+
*
|
|
19
|
+
* @param message The message to send. Messages must have a `type` property.
|
|
20
20
|
*/
|
|
21
|
-
|
|
21
|
+
sendMessage(message: any): void;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Load a module from the server.
|
|
24
|
+
* @param moduleName The name of the module to load.
|
|
25
|
+
* @returns A promise that resolves to the module.
|
|
24
26
|
*/
|
|
25
|
-
|
|
27
|
+
loadModule(moduleName: string): Promise<ReactPyModule>;
|
|
28
|
+
}
|
|
29
|
+
export declare abstract class BaseReactPyClient implements ReactPyClient {
|
|
30
|
+
private readonly handlers;
|
|
31
|
+
protected readonly ready: Promise<void>;
|
|
32
|
+
private resolveReady;
|
|
33
|
+
constructor();
|
|
34
|
+
onMessage(type: string, handler: (message: any) => void): () => void;
|
|
35
|
+
abstract sendMessage(message: any): void;
|
|
36
|
+
abstract loadModule(moduleName: string): Promise<ReactPyModule>;
|
|
26
37
|
/**
|
|
27
|
-
*
|
|
38
|
+
* Handle an incoming message.
|
|
39
|
+
*
|
|
40
|
+
* This should be called by subclasses when a message is received.
|
|
41
|
+
*
|
|
42
|
+
* @param message The message to handle. The message must have a `type` property.
|
|
28
43
|
*/
|
|
29
|
-
|
|
44
|
+
protected handleIncoming(message: any): void;
|
|
30
45
|
}
|
|
31
46
|
export type SimpleReactPyClientProps = {
|
|
32
47
|
serverLocation?: LocationProps;
|
|
@@ -68,19 +83,12 @@ type ReconnectProps = {
|
|
|
68
83
|
backoffRate?: number;
|
|
69
84
|
intervalJitter?: number;
|
|
70
85
|
};
|
|
71
|
-
export declare class SimpleReactPyClient implements ReactPyClient {
|
|
72
|
-
private resolveShouldOpen;
|
|
73
|
-
private resolveShouldClose;
|
|
86
|
+
export declare class SimpleReactPyClient extends BaseReactPyClient implements ReactPyClient {
|
|
74
87
|
private readonly urls;
|
|
75
|
-
private readonly handlers;
|
|
76
88
|
private readonly socket;
|
|
77
89
|
constructor(props: SimpleReactPyClientProps);
|
|
78
|
-
|
|
79
|
-
stop(): void;
|
|
80
|
-
onMessage<M extends IncomingMessage>(type: M["type"], handler: (message: M) => void): void;
|
|
81
|
-
sendMessage(message: OutgoingMessage): void;
|
|
90
|
+
sendMessage(message: any): void;
|
|
82
91
|
loadModule(moduleName: string): Promise<ReactPyModule>;
|
|
83
|
-
private handleIncoming;
|
|
84
92
|
}
|
|
85
93
|
export {};
|
|
86
94
|
//# sourceMappingURL=reactpy-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactpy-client.d.ts","sourceRoot":"","sources":["../src/reactpy-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"reactpy-client.d.ts","sourceRoot":"","sources":["../src/reactpy-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;;;;OAQG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAErE;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,CAAC;IAEhC;;;;OAIG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CACxD;AAED,8BAAsB,iBAAkB,YAAW,aAAa;IAC9D,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,MAAM,MAAM,wBAAwB,GAAG;IACrC,cAAc,CAAC,EAAE,aAAa,CAAC;IAC/B,gBAAgB,CAAC,EAAE,cAAc,CAAC;CACnC,CAAC;AAEF;;;;;;;;;GASG;AACH,KAAK,aAAa,GAAG;IACnB;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,qBAAa,mBACX,SAAQ,iBACR,YAAW,aAAa;IAExB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;gBAErC,KAAK,EAAE,wBAAwB;IAmB3C,WAAW,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAI/B,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;CAGvD"}
|
package/dist/reactpy-client.js
CHANGED
|
@@ -1,68 +1,62 @@
|
|
|
1
1
|
import logger from "./logger";
|
|
2
|
-
export class
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
export class BaseReactPyClient {
|
|
3
|
+
handlers = {};
|
|
4
|
+
ready;
|
|
5
|
+
resolveReady;
|
|
6
|
+
constructor() {
|
|
7
|
+
this.resolveReady = () => { };
|
|
8
|
+
this.ready = new Promise((resolve) => (this.resolveReady = resolve));
|
|
9
|
+
}
|
|
10
|
+
onMessage(type, handler) {
|
|
11
|
+
(this.handlers[type] || (this.handlers[type] = [])).push(handler);
|
|
12
|
+
this.resolveReady(undefined);
|
|
13
|
+
return () => {
|
|
14
|
+
this.handlers[type] = this.handlers[type].filter((h) => h !== handler);
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Handle an incoming message.
|
|
19
|
+
*
|
|
20
|
+
* This should be called by subclasses when a message is received.
|
|
21
|
+
*
|
|
22
|
+
* @param message The message to handle. The message must have a `type` property.
|
|
23
|
+
*/
|
|
24
|
+
handleIncoming(message) {
|
|
25
|
+
if (!message.type) {
|
|
26
|
+
logger.warn("Received message without type", message);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const messageHandlers = this.handlers[message.type];
|
|
30
|
+
if (!messageHandlers) {
|
|
31
|
+
logger.warn("Received message without handler", message);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
messageHandlers.forEach((h) => h(message));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export class SimpleReactPyClient extends BaseReactPyClient {
|
|
5
38
|
urls;
|
|
6
|
-
handlers;
|
|
7
39
|
socket;
|
|
8
40
|
constructor(props) {
|
|
9
|
-
|
|
10
|
-
"connection-open": [],
|
|
11
|
-
"connection-close": [],
|
|
12
|
-
"layout-update": [],
|
|
13
|
-
};
|
|
41
|
+
super();
|
|
14
42
|
this.urls = getServerUrls(props.serverLocation || {
|
|
15
43
|
url: document.location.origin,
|
|
16
44
|
route: document.location.pathname,
|
|
17
45
|
query: document.location.search,
|
|
18
46
|
});
|
|
19
|
-
this.
|
|
20
|
-
|
|
21
|
-
};
|
|
22
|
-
this.resolveShouldClose = () => {
|
|
23
|
-
throw new Error("Could not stop client");
|
|
24
|
-
};
|
|
25
|
-
const shouldOpen = new Promise((r) => (this.resolveShouldOpen = r));
|
|
26
|
-
const shouldClose = new Promise((r) => (this.resolveShouldClose = r));
|
|
27
|
-
this.socket = startReconnectingWebSocket({
|
|
28
|
-
shouldOpen,
|
|
29
|
-
shouldClose,
|
|
47
|
+
this.socket = createReconnectingWebSocket({
|
|
48
|
+
readyPromise: this.ready,
|
|
30
49
|
url: this.urls.stream,
|
|
31
|
-
onOpen: () => this.handleIncoming({ type: "connection-open" }),
|
|
32
50
|
onMessage: async ({ data }) => this.handleIncoming(JSON.parse(data)),
|
|
33
|
-
onClose: () => this.handleIncoming({ type: "connection-close" }),
|
|
34
51
|
...props.reconnectOptions,
|
|
35
52
|
});
|
|
36
53
|
}
|
|
37
|
-
start() {
|
|
38
|
-
logger.log("starting client...");
|
|
39
|
-
this.resolveShouldOpen(undefined);
|
|
40
|
-
}
|
|
41
|
-
stop() {
|
|
42
|
-
logger.log("stopping client...");
|
|
43
|
-
this.resolveShouldClose(undefined);
|
|
44
|
-
}
|
|
45
|
-
onMessage(type, handler) {
|
|
46
|
-
this.handlers[type].push(handler);
|
|
47
|
-
}
|
|
48
54
|
sendMessage(message) {
|
|
49
55
|
this.socket.current?.send(JSON.stringify(message));
|
|
50
56
|
}
|
|
51
57
|
loadModule(moduleName) {
|
|
52
58
|
return import(`${this.urls.modules}/${moduleName}`);
|
|
53
59
|
}
|
|
54
|
-
handleIncoming(message) {
|
|
55
|
-
if (!message.type) {
|
|
56
|
-
logger.warn("Received message without type", message);
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
const messageHandlers = this.handlers[message.type];
|
|
60
|
-
if (!messageHandlers) {
|
|
61
|
-
logger.warn("Received message without handler", message);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
messageHandlers.forEach((h) => h(message));
|
|
65
|
-
}
|
|
66
60
|
}
|
|
67
61
|
function getServerUrls(props) {
|
|
68
62
|
const base = new URL(`${props.url || document.location.origin}/_reactpy`);
|
|
@@ -73,12 +67,12 @@ function getServerUrls(props) {
|
|
|
73
67
|
const stream = `${streamProtocol}://${base.host}${streamPath}${props.query}`;
|
|
74
68
|
return { base, modules, assets, stream };
|
|
75
69
|
}
|
|
76
|
-
function
|
|
70
|
+
function createReconnectingWebSocket(props) {
|
|
77
71
|
const { maxInterval = 60000, maxRetries = 50, backoffRate = 1.1, intervalJitter = 0.1, } = props;
|
|
78
72
|
const startInterval = 750;
|
|
79
73
|
let retries = 0;
|
|
80
74
|
let interval = startInterval;
|
|
81
|
-
|
|
75
|
+
const closed = false;
|
|
82
76
|
let everConnected = false;
|
|
83
77
|
const socket = {};
|
|
84
78
|
const connect = () => {
|
|
@@ -91,7 +85,9 @@ function startReconnectingWebSocket(props) {
|
|
|
91
85
|
logger.log("client connected");
|
|
92
86
|
interval = startInterval;
|
|
93
87
|
retries = 0;
|
|
94
|
-
props.onOpen
|
|
88
|
+
if (props.onOpen) {
|
|
89
|
+
props.onOpen();
|
|
90
|
+
}
|
|
95
91
|
};
|
|
96
92
|
socket.current.onmessage = props.onMessage;
|
|
97
93
|
socket.current.onclose = () => {
|
|
@@ -100,7 +96,9 @@ function startReconnectingWebSocket(props) {
|
|
|
100
96
|
return;
|
|
101
97
|
}
|
|
102
98
|
logger.log("client disconnected");
|
|
103
|
-
props.onClose
|
|
99
|
+
if (props.onClose) {
|
|
100
|
+
props.onClose();
|
|
101
|
+
}
|
|
104
102
|
if (retries >= maxRetries) {
|
|
105
103
|
return;
|
|
106
104
|
}
|
|
@@ -111,11 +109,7 @@ function startReconnectingWebSocket(props) {
|
|
|
111
109
|
retries++;
|
|
112
110
|
};
|
|
113
111
|
};
|
|
114
|
-
props.
|
|
115
|
-
props.shouldClose.then(() => {
|
|
116
|
-
closed = true;
|
|
117
|
-
socket.current?.close();
|
|
118
|
-
});
|
|
112
|
+
props.readyPromise.then(() => logger.log("starting client...")).then(connect);
|
|
119
113
|
return socket;
|
|
120
114
|
}
|
|
121
115
|
function nextInterval(currentInterval, backoffRate, maxInterval) {
|
|
@@ -131,3 +125,4 @@ function addJitter(interval, jitter) {
|
|
|
131
125
|
function rtrim(text, trim) {
|
|
132
126
|
return text.replace(new RegExp(`${trim}+$`), "");
|
|
133
127
|
}
|
|
128
|
+
//# sourceMappingURL=reactpy-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactpy-client.js","sourceRoot":"","sources":["../src/reactpy-client.ts"],"names":[],"mappings":"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"}
|
package/dist/reactpy-vdom.js
CHANGED
|
@@ -98,8 +98,8 @@ export function createAttributes(model, client) {
|
|
|
98
98
|
function createEventHandler(client, name, { target, preventDefault, stopPropagation }) {
|
|
99
99
|
return [
|
|
100
100
|
name,
|
|
101
|
-
function () {
|
|
102
|
-
const data = Array.from(
|
|
101
|
+
function (...args) {
|
|
102
|
+
const data = Array.from(args).map((value) => {
|
|
103
103
|
if (!(typeof value === "object" && value.nativeEvent)) {
|
|
104
104
|
return value;
|
|
105
105
|
}
|
|
@@ -138,3 +138,4 @@ function snakeToCamel(str) {
|
|
|
138
138
|
// see list of HTML attributes with dashes in them:
|
|
139
139
|
// https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes#attribute_list
|
|
140
140
|
const DASHED_HTML_ATTRS = ["accept_charset", "http_equiv"];
|
|
141
|
+
//# sourceMappingURL=reactpy-vdom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactpy-vdom.js","sourceRoot":"","sources":["../src/reactpy-vdom.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"name": "@reactpy/client",
|
|
8
8
|
"type": "module",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.3.1",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"event-to-object": "^0.1.2",
|
|
12
12
|
"json-pointer": "^0.6.2"
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
"@types/json-pointer": "^1.0.31",
|
|
16
16
|
"@types/react": "^17.0",
|
|
17
17
|
"@types/react-dom": "^17.0",
|
|
18
|
-
"prettier": "^3.0.0-alpha.6",
|
|
19
18
|
"typescript": "^4.9.5"
|
|
20
19
|
},
|
|
21
20
|
"peerDependencies": {
|
|
@@ -28,9 +27,7 @@
|
|
|
28
27
|
},
|
|
29
28
|
"scripts": {
|
|
30
29
|
"build": "tsc -b",
|
|
31
|
-
"format": "prettier --write .",
|
|
32
30
|
"test": "npm run check:tests",
|
|
33
|
-
"check:format": "prettier --check .",
|
|
34
31
|
"check:tests": "echo 'no tests'",
|
|
35
32
|
"check:types": "tsc --noEmit"
|
|
36
33
|
}
|
package/src/components.tsx
CHANGED
|
@@ -11,7 +11,6 @@ import React, {
|
|
|
11
11
|
} from "react";
|
|
12
12
|
// @ts-ignore
|
|
13
13
|
import { set as setJsonPointer } from "json-pointer";
|
|
14
|
-
import { LayoutUpdateMessage } from "./messages";
|
|
15
14
|
import {
|
|
16
15
|
ReactPyVdom,
|
|
17
16
|
ReactPyComponent,
|
|
@@ -28,21 +27,18 @@ export function Layout(props: { client: ReactPyClient }): JSX.Element {
|
|
|
28
27
|
const currentModel: ReactPyVdom = useState({ tagName: "" })[0];
|
|
29
28
|
const forceUpdate = useForceUpdate();
|
|
30
29
|
|
|
31
|
-
useEffect(
|
|
32
|
-
|
|
33
|
-
"layout-update",
|
|
34
|
-
({ path, model }) => {
|
|
30
|
+
useEffect(
|
|
31
|
+
() =>
|
|
32
|
+
props.client.onMessage("layout-update", ({ path, model }) => {
|
|
35
33
|
if (path === "") {
|
|
36
34
|
Object.assign(currentModel, model);
|
|
37
35
|
} else {
|
|
38
36
|
setJsonPointer(currentModel, path, model);
|
|
39
37
|
}
|
|
40
38
|
forceUpdate();
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return () => props.client.stop();
|
|
45
|
-
}, [currentModel, props.client]);
|
|
39
|
+
}),
|
|
40
|
+
[currentModel, props.client],
|
|
41
|
+
);
|
|
46
42
|
|
|
47
43
|
return (
|
|
48
44
|
<ClientContext.Provider value={props.client}>
|
|
@@ -140,7 +136,7 @@ function ScriptElement({ model }: { model: ReactPyVdom }) {
|
|
|
140
136
|
}
|
|
141
137
|
ref.current.appendChild(scriptElement);
|
|
142
138
|
} else if (scriptContent) {
|
|
143
|
-
|
|
139
|
+
const scriptResult = eval(scriptContent);
|
|
144
140
|
if (typeof scriptResult == "function") {
|
|
145
141
|
return scriptResult();
|
|
146
142
|
}
|
package/src/messages.ts
CHANGED
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
import { ReactPyVdom } from "./reactpy-vdom";
|
|
2
2
|
|
|
3
|
-
export interface IMessage {
|
|
4
|
-
type: string;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export type ConnectionOpenMessage = {
|
|
8
|
-
type: "connection-open";
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export type ConnectionCloseMessage = {
|
|
12
|
-
type: "connection-close";
|
|
13
|
-
};
|
|
14
|
-
|
|
15
3
|
export type LayoutUpdateMessage = {
|
|
16
4
|
type: "layout-update";
|
|
17
5
|
path: string;
|
|
@@ -24,9 +12,6 @@ export type LayoutEventMessage = {
|
|
|
24
12
|
data: any;
|
|
25
13
|
};
|
|
26
14
|
|
|
27
|
-
export type IncomingMessage =
|
|
28
|
-
| LayoutUpdateMessage
|
|
29
|
-
| ConnectionOpenMessage
|
|
30
|
-
| ConnectionCloseMessage;
|
|
15
|
+
export type IncomingMessage = LayoutUpdateMessage;
|
|
31
16
|
export type OutgoingMessage = LayoutEventMessage;
|
|
32
17
|
export type Message = IncomingMessage | OutgoingMessage;
|
package/src/reactpy-client.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { OutgoingMessage, IncomingMessage } from "./messages";
|
|
2
1
|
import { ReactPyModule } from "./reactpy-vdom";
|
|
3
2
|
import logger from "./logger";
|
|
4
3
|
|
|
@@ -7,31 +6,74 @@ import logger from "./logger";
|
|
|
7
6
|
*/
|
|
8
7
|
export interface ReactPyClient {
|
|
9
8
|
/**
|
|
10
|
-
*
|
|
9
|
+
* Register a handler for a message type.
|
|
11
10
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
* Disconnect from the server and stop receiving messages.
|
|
11
|
+
* The first time this is called, the client will be considered ready.
|
|
12
|
+
*
|
|
13
|
+
* @param type The type of message to handle.
|
|
14
|
+
* @param handler The handler to call when a message of the given type is received.
|
|
15
|
+
* @returns A function to unregister the handler.
|
|
18
16
|
*/
|
|
19
|
-
|
|
17
|
+
onMessage(type: string, handler: (message: any) => void): () => void;
|
|
18
|
+
|
|
20
19
|
/**
|
|
21
|
-
*
|
|
20
|
+
* Send a message to the server.
|
|
21
|
+
*
|
|
22
|
+
* @param message The message to send. Messages must have a `type` property.
|
|
22
23
|
*/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
handler: (message: M) => void,
|
|
26
|
-
) => void;
|
|
24
|
+
sendMessage(message: any): void;
|
|
25
|
+
|
|
27
26
|
/**
|
|
28
|
-
*
|
|
27
|
+
* Load a module from the server.
|
|
28
|
+
* @param moduleName The name of the module to load.
|
|
29
|
+
* @returns A promise that resolves to the module.
|
|
29
30
|
*/
|
|
30
|
-
|
|
31
|
+
loadModule(moduleName: string): Promise<ReactPyModule>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export abstract class BaseReactPyClient implements ReactPyClient {
|
|
35
|
+
private readonly handlers: { [key: string]: ((message: any) => void)[] } = {};
|
|
36
|
+
protected readonly ready: Promise<void>;
|
|
37
|
+
private resolveReady: (value: undefined) => void;
|
|
38
|
+
|
|
39
|
+
constructor() {
|
|
40
|
+
this.resolveReady = () => {};
|
|
41
|
+
this.ready = new Promise((resolve) => (this.resolveReady = resolve));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
onMessage(type: string, handler: (message: any) => void): () => void {
|
|
45
|
+
(this.handlers[type] || (this.handlers[type] = [])).push(handler);
|
|
46
|
+
this.resolveReady(undefined);
|
|
47
|
+
return () => {
|
|
48
|
+
this.handlers[type] = this.handlers[type].filter((h) => h !== handler);
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
abstract sendMessage(message: any): void;
|
|
53
|
+
abstract loadModule(moduleName: string): Promise<ReactPyModule>;
|
|
54
|
+
|
|
31
55
|
/**
|
|
32
|
-
*
|
|
56
|
+
* Handle an incoming message.
|
|
57
|
+
*
|
|
58
|
+
* This should be called by subclasses when a message is received.
|
|
59
|
+
*
|
|
60
|
+
* @param message The message to handle. The message must have a `type` property.
|
|
33
61
|
*/
|
|
34
|
-
|
|
62
|
+
protected handleIncoming(message: any): void {
|
|
63
|
+
if (!message.type) {
|
|
64
|
+
logger.warn("Received message without type", message);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const messageHandlers: ((m: any) => void)[] | undefined =
|
|
69
|
+
this.handlers[message.type];
|
|
70
|
+
if (!messageHandlers) {
|
|
71
|
+
logger.warn("Received message without handler", message);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
messageHandlers.forEach((h) => h(message));
|
|
76
|
+
}
|
|
35
77
|
}
|
|
36
78
|
|
|
37
79
|
export type SimpleReactPyClientProps = {
|
|
@@ -77,21 +119,15 @@ type ReconnectProps = {
|
|
|
77
119
|
intervalJitter?: number;
|
|
78
120
|
};
|
|
79
121
|
|
|
80
|
-
export class SimpleReactPyClient
|
|
81
|
-
|
|
82
|
-
|
|
122
|
+
export class SimpleReactPyClient
|
|
123
|
+
extends BaseReactPyClient
|
|
124
|
+
implements ReactPyClient
|
|
125
|
+
{
|
|
83
126
|
private readonly urls: ServerUrls;
|
|
84
|
-
private readonly handlers: {
|
|
85
|
-
[key in IncomingMessage["type"]]: ((message: any) => void)[];
|
|
86
|
-
};
|
|
87
127
|
private readonly socket: { current?: WebSocket };
|
|
88
128
|
|
|
89
129
|
constructor(props: SimpleReactPyClientProps) {
|
|
90
|
-
|
|
91
|
-
"connection-open": [],
|
|
92
|
-
"connection-close": [],
|
|
93
|
-
"layout-update": [],
|
|
94
|
-
};
|
|
130
|
+
super();
|
|
95
131
|
|
|
96
132
|
this.urls = getServerUrls(
|
|
97
133
|
props.serverLocation || {
|
|
@@ -101,66 +137,21 @@ export class SimpleReactPyClient implements ReactPyClient {
|
|
|
101
137
|
},
|
|
102
138
|
);
|
|
103
139
|
|
|
104
|
-
this.
|
|
105
|
-
|
|
106
|
-
};
|
|
107
|
-
this.resolveShouldClose = () => {
|
|
108
|
-
throw new Error("Could not stop client");
|
|
109
|
-
};
|
|
110
|
-
const shouldOpen = new Promise((r) => (this.resolveShouldOpen = r));
|
|
111
|
-
const shouldClose = new Promise((r) => (this.resolveShouldClose = r));
|
|
112
|
-
|
|
113
|
-
this.socket = startReconnectingWebSocket({
|
|
114
|
-
shouldOpen,
|
|
115
|
-
shouldClose,
|
|
140
|
+
this.socket = createReconnectingWebSocket({
|
|
141
|
+
readyPromise: this.ready,
|
|
116
142
|
url: this.urls.stream,
|
|
117
|
-
onOpen: () => this.handleIncoming({ type: "connection-open" }),
|
|
118
143
|
onMessage: async ({ data }) => this.handleIncoming(JSON.parse(data)),
|
|
119
|
-
onClose: () => this.handleIncoming({ type: "connection-close" }),
|
|
120
144
|
...props.reconnectOptions,
|
|
121
145
|
});
|
|
122
146
|
}
|
|
123
147
|
|
|
124
|
-
|
|
125
|
-
logger.log("starting client...");
|
|
126
|
-
this.resolveShouldOpen(undefined);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
stop(): void {
|
|
130
|
-
logger.log("stopping client...");
|
|
131
|
-
this.resolveShouldClose(undefined);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
onMessage<M extends IncomingMessage>(
|
|
135
|
-
type: M["type"],
|
|
136
|
-
handler: (message: M) => void,
|
|
137
|
-
): void {
|
|
138
|
-
this.handlers[type].push(handler);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
sendMessage(message: OutgoingMessage): void {
|
|
148
|
+
sendMessage(message: any): void {
|
|
142
149
|
this.socket.current?.send(JSON.stringify(message));
|
|
143
150
|
}
|
|
144
151
|
|
|
145
152
|
loadModule(moduleName: string): Promise<ReactPyModule> {
|
|
146
153
|
return import(`${this.urls.modules}/${moduleName}`);
|
|
147
154
|
}
|
|
148
|
-
|
|
149
|
-
private handleIncoming(message: IncomingMessage): void {
|
|
150
|
-
if (!message.type) {
|
|
151
|
-
logger.warn("Received message without type", message);
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const messageHandlers: ((m: any) => void)[] | undefined =
|
|
156
|
-
this.handlers[message.type];
|
|
157
|
-
if (!messageHandlers) {
|
|
158
|
-
logger.warn("Received message without handler", message);
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
messageHandlers.forEach((h) => h(message));
|
|
163
|
-
}
|
|
164
155
|
}
|
|
165
156
|
|
|
166
157
|
type ServerUrls = {
|
|
@@ -182,14 +173,13 @@ function getServerUrls(props: LocationProps): ServerUrls {
|
|
|
182
173
|
return { base, modules, assets, stream };
|
|
183
174
|
}
|
|
184
175
|
|
|
185
|
-
function
|
|
176
|
+
function createReconnectingWebSocket(
|
|
186
177
|
props: {
|
|
187
|
-
shouldOpen: Promise<any>;
|
|
188
|
-
shouldClose: Promise<any>;
|
|
189
178
|
url: string;
|
|
190
|
-
|
|
179
|
+
readyPromise: Promise<void>;
|
|
180
|
+
onOpen?: () => void;
|
|
191
181
|
onMessage: (message: MessageEvent<any>) => void;
|
|
192
|
-
onClose
|
|
182
|
+
onClose?: () => void;
|
|
193
183
|
} & ReconnectProps,
|
|
194
184
|
) {
|
|
195
185
|
const {
|
|
@@ -202,7 +192,7 @@ function startReconnectingWebSocket(
|
|
|
202
192
|
const startInterval = 750;
|
|
203
193
|
let retries = 0;
|
|
204
194
|
let interval = startInterval;
|
|
205
|
-
|
|
195
|
+
const closed = false;
|
|
206
196
|
let everConnected = false;
|
|
207
197
|
const socket: { current?: WebSocket } = {};
|
|
208
198
|
|
|
@@ -216,7 +206,9 @@ function startReconnectingWebSocket(
|
|
|
216
206
|
logger.log("client connected");
|
|
217
207
|
interval = startInterval;
|
|
218
208
|
retries = 0;
|
|
219
|
-
props.onOpen
|
|
209
|
+
if (props.onOpen) {
|
|
210
|
+
props.onOpen();
|
|
211
|
+
}
|
|
220
212
|
};
|
|
221
213
|
socket.current.onmessage = props.onMessage;
|
|
222
214
|
socket.current.onclose = () => {
|
|
@@ -226,7 +218,9 @@ function startReconnectingWebSocket(
|
|
|
226
218
|
}
|
|
227
219
|
|
|
228
220
|
logger.log("client disconnected");
|
|
229
|
-
props.onClose
|
|
221
|
+
if (props.onClose) {
|
|
222
|
+
props.onClose();
|
|
223
|
+
}
|
|
230
224
|
|
|
231
225
|
if (retries >= maxRetries) {
|
|
232
226
|
return;
|
|
@@ -242,11 +236,7 @@ function startReconnectingWebSocket(
|
|
|
242
236
|
};
|
|
243
237
|
};
|
|
244
238
|
|
|
245
|
-
props.
|
|
246
|
-
props.shouldClose.then(() => {
|
|
247
|
-
closed = true;
|
|
248
|
-
socket.current?.close();
|
|
249
|
-
});
|
|
239
|
+
props.readyPromise.then(() => logger.log("starting client...")).then(connect);
|
|
250
240
|
|
|
251
241
|
return socket;
|
|
252
242
|
}
|
package/src/reactpy-vdom.tsx
CHANGED
|
@@ -155,8 +155,8 @@ function createEventHandler(
|
|
|
155
155
|
): [string, () => void] {
|
|
156
156
|
return [
|
|
157
157
|
name,
|
|
158
|
-
function () {
|
|
159
|
-
const data = Array.from(
|
|
158
|
+
function (...args: any[]) {
|
|
159
|
+
const data = Array.from(args).map((value) => {
|
|
160
160
|
if (!(typeof value === "object" && value.nativeEvent)) {
|
|
161
161
|
return value;
|
|
162
162
|
}
|