@reactpy/client 1.0.3 → 1.2.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/dist/bind.d.ts.map +1 -1
- package/dist/bind.js +1 -2
- package/dist/bind.js.map +1 -1
- package/dist/client.d.ts +1 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +13 -1
- package/dist/client.js.map +1 -1
- package/dist/components.d.ts +6 -0
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +141 -10
- package/dist/components.js.map +1 -1
- package/dist/handler.d.ts +26 -0
- package/dist/handler.d.ts.map +1 -0
- package/dist/handler.js +38 -0
- package/dist/handler.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mount.d.ts.map +1 -1
- package/dist/mount.js +2 -2
- package/dist/mount.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/vdom.d.ts +1 -1
- package/dist/vdom.d.ts.map +1 -1
- package/dist/vdom.js +21 -2
- package/dist/vdom.js.map +1 -1
- package/dist/websocket.d.ts.map +1 -1
- package/dist/websocket.js +13 -0
- package/dist/websocket.js.map +1 -1
- package/package.json +1 -1
- package/src/bind.tsx +2 -3
- package/src/client.ts +14 -1
- package/src/components.tsx +196 -11
- package/src/handler.ts +56 -0
- package/src/index.ts +1 -0
- package/src/mount.tsx +2 -5
- package/src/types.ts +2 -0
- package/src/vdom.tsx +46 -12
- package/src/websocket.ts +14 -0
package/dist/bind.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../src/bind.tsx"],"names":[],"mappings":"AAEA,wBAAsB,2BAA2B,mBAM/B,WAAW;
|
|
1
|
+
{"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../src/bind.tsx"],"names":[],"mappings":"AAEA,wBAAsB,2BAA2B,mBAM/B,WAAW;mBAyBV,GAAG,SAAS,GAAG,aAAa,GAAG,EAAE;sBAE9B,GAAG;;GApBxB"}
|
package/dist/bind.js
CHANGED
|
@@ -8,8 +8,7 @@ export async function infer_bind_from_environment() {
|
|
|
8
8
|
return (node) => reactjs_bind(node, React, ReactDOM);
|
|
9
9
|
}
|
|
10
10
|
catch {
|
|
11
|
-
console.
|
|
12
|
-
Your JavaScript components may not work as expected!");
|
|
11
|
+
console.debug("ReactPy will render JavaScript components using internal bindings for 'react'.");
|
|
13
12
|
return (node) => local_preact_bind(node);
|
|
14
13
|
}
|
|
15
14
|
}
|
package/dist/bind.js.map
CHANGED
|
@@ -1 +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
|
|
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,gFAAgF,CACjF,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
CHANGED
|
@@ -22,6 +22,7 @@ export declare class ReactPyClient extends BaseReactPyClient implements ReactPyC
|
|
|
22
22
|
current?: WebSocket;
|
|
23
23
|
};
|
|
24
24
|
mountElement: HTMLElement;
|
|
25
|
+
private readonly messageQueue;
|
|
25
26
|
constructor(props: GenericReactPyClientProps);
|
|
26
27
|
sendMessage(message: any): void;
|
|
27
28
|
loadModule(moduleName: string): Promise<ReactPyModule>;
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +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;
|
|
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;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAa;gBAE9B,KAAK,EAAE,yBAAyB;IAkB5C,WAAW,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAW/B,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;CAGvD"}
|
package/dist/client.js
CHANGED
|
@@ -39,6 +39,7 @@ export class ReactPyClient extends BaseReactPyClient {
|
|
|
39
39
|
urls;
|
|
40
40
|
socket;
|
|
41
41
|
mountElement;
|
|
42
|
+
messageQueue = [];
|
|
42
43
|
constructor(props) {
|
|
43
44
|
super();
|
|
44
45
|
this.urls = props.urls;
|
|
@@ -47,11 +48,22 @@ export class ReactPyClient extends BaseReactPyClient {
|
|
|
47
48
|
url: this.urls.componentUrl,
|
|
48
49
|
readyPromise: this.ready,
|
|
49
50
|
...props.reconnectOptions,
|
|
51
|
+
onOpen: () => {
|
|
52
|
+
while (this.messageQueue.length > 0) {
|
|
53
|
+
this.sendMessage(this.messageQueue.shift());
|
|
54
|
+
}
|
|
55
|
+
},
|
|
50
56
|
onMessage: async ({ data }) => this.handleIncoming(JSON.parse(data)),
|
|
51
57
|
});
|
|
52
58
|
}
|
|
53
59
|
sendMessage(message) {
|
|
54
|
-
this.socket.current
|
|
60
|
+
if (this.socket.current &&
|
|
61
|
+
this.socket.current.readyState === WebSocket.OPEN) {
|
|
62
|
+
this.socket.current.send(JSON.stringify(message));
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
this.messageQueue.push(message);
|
|
66
|
+
}
|
|
55
67
|
}
|
|
56
68
|
loadModule(moduleName) {
|
|
57
69
|
return import(`${this.urls.jsModulesPath}${moduleName}`);
|
package/dist/client.js.map
CHANGED
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/components.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { type JSX } from "preact";
|
|
2
2
|
import type { ReactPyVdom } from "./types";
|
|
3
3
|
import type { ReactPyClient } from "./client";
|
|
4
|
+
/**
|
|
5
|
+
* Return the built-in default debounce (ms) for an element type.
|
|
6
|
+
* Inputs default to 200 ms to preserve text-input coherency against
|
|
7
|
+
* server-driven ``value`` updates; all other elements default to 0 ms.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getDefaultDebounceMs(tagName: string): number;
|
|
4
10
|
export declare function Layout(props: {
|
|
5
11
|
client: ReactPyClient;
|
|
6
12
|
}): JSX.Element;
|
package/dist/components.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/components.tsx"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,GAAG,EAET,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/components.tsx"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,GAAG,EAET,MAAM,QAAQ,CAAC;AAUhB,OAAO,KAAK,EAGV,WAAW,EACZ,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAa9C;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAI5D;AAoFD,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
|
@@ -2,8 +2,85 @@ import { jsx as _jsx } from "preact/jsx-runtime";
|
|
|
2
2
|
import { set as setJsonPointer } from "json-pointer";
|
|
3
3
|
import { createContext, createElement, Fragment, } from "preact";
|
|
4
4
|
import { useContext, useEffect, useRef, useState } from "preact/hooks";
|
|
5
|
+
import { HANDLER_DEBOUNCE, HANDLER_MARKER, HANDLER_THROTTLE, getInitialDebounce, isValidDebounce, } from "./handler";
|
|
5
6
|
import { createAttributes, createChildren, loadImportSource } from "./vdom";
|
|
6
7
|
const ClientContext = createContext(null);
|
|
8
|
+
// Built-in default debounce (ms) used by user-input elements (``<input>``,
|
|
9
|
+
// ``<select>``, ``<textarea>``) when no per-handler ``debounce`` is set.
|
|
10
|
+
// Non-input elements default to 0 ms (no debounce) — set ``debounce`` or
|
|
11
|
+
// ``throttle`` explicitly on the handler if you need either behavior.
|
|
12
|
+
const DEFAULT_INPUT_DEBOUNCE_MS = 200;
|
|
13
|
+
const DEFAULT_NON_INPUT_DEBOUNCE_MS = 0;
|
|
14
|
+
const USER_INPUT_TAGS = new Set(["input", "select", "textarea"]);
|
|
15
|
+
/**
|
|
16
|
+
* Return the built-in default debounce (ms) for an element type.
|
|
17
|
+
* Inputs default to 200 ms to preserve text-input coherency against
|
|
18
|
+
* server-driven ``value`` updates; all other elements default to 0 ms.
|
|
19
|
+
*/
|
|
20
|
+
export function getDefaultDebounceMs(tagName) {
|
|
21
|
+
return USER_INPUT_TAGS.has(tagName)
|
|
22
|
+
? DEFAULT_INPUT_DEBOUNCE_MS
|
|
23
|
+
: DEFAULT_NON_INPUT_DEBOUNCE_MS;
|
|
24
|
+
}
|
|
25
|
+
function trackUserInput(event, setValue, lastUserValue, lastChangeTime, lastInputDebounce, debounce) {
|
|
26
|
+
if (!event.target) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const newValue = event.target.value;
|
|
30
|
+
setValue(newValue);
|
|
31
|
+
lastUserValue.current = newValue;
|
|
32
|
+
lastChangeTime.current = Date.now();
|
|
33
|
+
lastInputDebounce.current = debounce;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Wrap ``handler`` so its outgoing call is throttled to at most once per
|
|
37
|
+
* ``intervalMs`` milliseconds. Subsequent calls inside the window are
|
|
38
|
+
* collapsed and the trailing call (with the most recent arguments) fires
|
|
39
|
+
* once the window expires.
|
|
40
|
+
*
|
|
41
|
+
* Returns the original handler unchanged when ``intervalMs`` is missing or
|
|
42
|
+
* invalid.
|
|
43
|
+
*/
|
|
44
|
+
function throttleHandler(handler, intervalMs) {
|
|
45
|
+
if (!isValidDebounce(intervalMs)) {
|
|
46
|
+
return handler;
|
|
47
|
+
}
|
|
48
|
+
let pendingArgs = null;
|
|
49
|
+
let timer = null;
|
|
50
|
+
let lastFireTime = 0;
|
|
51
|
+
const wrapped = function (...args) {
|
|
52
|
+
const now = Date.now();
|
|
53
|
+
const elapsed = now - lastFireTime;
|
|
54
|
+
if (elapsed >= intervalMs) {
|
|
55
|
+
// Leading edge: fire immediately, then start a cooldown.
|
|
56
|
+
lastFireTime = now;
|
|
57
|
+
handler(...args);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// Trailing edge: remember the latest args and schedule a fire at the
|
|
61
|
+
// end of the cooldown so no event is silently dropped.
|
|
62
|
+
pendingArgs = args;
|
|
63
|
+
if (timer === null) {
|
|
64
|
+
timer = window.setTimeout(() => {
|
|
65
|
+
timer = null;
|
|
66
|
+
if (pendingArgs !== null) {
|
|
67
|
+
const callArgs = pendingArgs;
|
|
68
|
+
pendingArgs = null;
|
|
69
|
+
lastFireTime = Date.now();
|
|
70
|
+
handler(...callArgs);
|
|
71
|
+
}
|
|
72
|
+
}, Math.max(0, intervalMs - elapsed));
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
// Preserve the tag markers so downstream code can still introspect the
|
|
76
|
+
// wrapped function.
|
|
77
|
+
wrapped[HANDLER_MARKER] = true;
|
|
78
|
+
const debounce = handler[HANDLER_DEBOUNCE];
|
|
79
|
+
if (typeof debounce === "number") {
|
|
80
|
+
wrapped[HANDLER_DEBOUNCE] = debounce;
|
|
81
|
+
}
|
|
82
|
+
return wrapped;
|
|
83
|
+
}
|
|
7
84
|
export function Layout(props) {
|
|
8
85
|
const currentModel = useState({ tagName: "" })[0];
|
|
9
86
|
const forceUpdate = useForceUpdate();
|
|
@@ -42,10 +119,27 @@ export function Element({ model }) {
|
|
|
42
119
|
}
|
|
43
120
|
function StandardElement({ model }) {
|
|
44
121
|
const client = useContext(ClientContext);
|
|
122
|
+
const attrs = createAttributes(model, client);
|
|
123
|
+
// Apply the throttle wrapper to tagged handlers. ``debounce`` (server-→
|
|
124
|
+
// client value reconciliation) only applies to user-input elements, so
|
|
125
|
+
// it's intentionally ignored here; ``throttle`` works everywhere.
|
|
126
|
+
for (const [name, prop] of Object.entries(attrs)) {
|
|
127
|
+
if (typeof prop !== "function") {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
const handler = prop;
|
|
131
|
+
if (!handler[HANDLER_MARKER]) {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const throttle = handler[HANDLER_THROTTLE];
|
|
135
|
+
if (isValidDebounce(throttle)) {
|
|
136
|
+
attrs[name] = throttleHandler(handler, throttle);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
45
139
|
// Use createElement here to avoid warning about variable numbers of children not
|
|
46
140
|
// having keys. Warning about this must now be the responsibility of the client
|
|
47
141
|
// providing the models instead of the client rendering them.
|
|
48
|
-
return createElement(model.tagName === "" ? Fragment : model.tagName,
|
|
142
|
+
return createElement(model.tagName === "" ? Fragment : model.tagName, attrs, ...createChildren(model, (child) => {
|
|
49
143
|
return _jsx(Element, { model: child }, child.attributes?.key);
|
|
50
144
|
}));
|
|
51
145
|
}
|
|
@@ -53,17 +147,54 @@ function UserInputElement({ model }) {
|
|
|
53
147
|
const client = useContext(ClientContext);
|
|
54
148
|
const props = createAttributes(model, client);
|
|
55
149
|
const [value, setValue] = useState(props.value);
|
|
150
|
+
const lastUserValue = useRef(props.value);
|
|
151
|
+
const lastChangeTime = useRef(0);
|
|
152
|
+
// Seed the debounce window from the handlers themselves when possible,
|
|
153
|
+
// otherwise fall back to the per-tagName built-in default (200 ms for
|
|
154
|
+
// user-input tags, 0 ms elsewhere). This ensures the very first
|
|
155
|
+
// server-driven update already respects the configured debounce.
|
|
156
|
+
const lastInputDebounce = useRef(getInitialDebounce(props, getDefaultDebounceMs(model.tagName)));
|
|
157
|
+
const reconcileTimeout = useRef(null);
|
|
56
158
|
// honor changes to value from the client via props
|
|
57
|
-
useEffect(() =>
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (
|
|
63
|
-
|
|
159
|
+
useEffect(() => {
|
|
160
|
+
const reconcileValue = () => {
|
|
161
|
+
// If the new prop value matches what we last sent, we are in sync.
|
|
162
|
+
// If it differs, wait until the debounce window expires before applying it.
|
|
163
|
+
const elapsed = Date.now() - lastChangeTime.current;
|
|
164
|
+
if (props.value === lastUserValue.current ||
|
|
165
|
+
elapsed >= lastInputDebounce.current) {
|
|
166
|
+
reconcileTimeout.current = null;
|
|
167
|
+
setValue(props.value);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
reconcileTimeout.current = window.setTimeout(reconcileValue, Math.max(0, lastInputDebounce.current - elapsed));
|
|
171
|
+
};
|
|
172
|
+
reconcileValue();
|
|
173
|
+
return () => {
|
|
174
|
+
if (reconcileTimeout.current !== null) {
|
|
175
|
+
window.clearTimeout(reconcileTimeout.current);
|
|
176
|
+
reconcileTimeout.current = null;
|
|
64
177
|
}
|
|
65
|
-
|
|
66
|
-
|
|
178
|
+
};
|
|
179
|
+
}, [props.value]);
|
|
180
|
+
for (const [name, prop] of Object.entries(props)) {
|
|
181
|
+
if (typeof prop !== "function") {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
const givenHandler = prop;
|
|
185
|
+
if (!givenHandler[HANDLER_MARKER]) {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const handlerDebounce = givenHandler[HANDLER_DEBOUNCE];
|
|
189
|
+
const effectiveDebounce = isValidDebounce(handlerDebounce)
|
|
190
|
+
? handlerDebounce
|
|
191
|
+
: getDefaultDebounceMs(model.tagName);
|
|
192
|
+
const throttled = isValidDebounce(givenHandler[HANDLER_THROTTLE])
|
|
193
|
+
? throttleHandler(givenHandler, givenHandler[HANDLER_THROTTLE])
|
|
194
|
+
: givenHandler;
|
|
195
|
+
props[name] = (event) => {
|
|
196
|
+
trackUserInput(event, setValue, lastUserValue, lastChangeTime, lastInputDebounce, effectiveDebounce);
|
|
197
|
+
throttled(event);
|
|
67
198
|
};
|
|
68
199
|
}
|
|
69
200
|
// Use createElement here to avoid warning about variable numbers of children not
|
package/dist/components.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.js","sourceRoot":"","sources":["../src/components.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,IAAI,cAAc,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,EACL,aAAa,EACb,aAAa,EACb,QAAQ,GAGT,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"components.js","sourceRoot":"","sources":["../src/components.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare const HANDLER_MARKER: "isHandler";
|
|
2
|
+
export declare const HANDLER_DEBOUNCE: "debounce";
|
|
3
|
+
export declare const HANDLER_THROTTLE: "throttle";
|
|
4
|
+
export type HandlerMarker = typeof HANDLER_MARKER;
|
|
5
|
+
export type HandlerDebounce = typeof HANDLER_DEBOUNCE;
|
|
6
|
+
export type HandlerThrottle = typeof HANDLER_THROTTLE;
|
|
7
|
+
export type TaggedEventHandler = ((event: Event) => void) & {
|
|
8
|
+
[HANDLER_MARKER]: true;
|
|
9
|
+
[HANDLER_DEBOUNCE]?: number;
|
|
10
|
+
[HANDLER_THROTTLE]?: number;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Returns the debounce value (in milliseconds) to use as the default for a user
|
|
14
|
+
* input element when no user input has been recorded yet. Uses the maximum
|
|
15
|
+
* debounce among the element's tagged handlers, falling back to the global
|
|
16
|
+
* default if none of the handlers specify one.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getInitialDebounce(props: Record<string, unknown>, fallback: number): number;
|
|
19
|
+
/**
|
|
20
|
+
* Returns true when the given value is a finite, non-negative integer.
|
|
21
|
+
* Used to validate debounce/throttle values arriving over the wire from the
|
|
22
|
+
* Python layout.
|
|
23
|
+
*/
|
|
24
|
+
export declare function isValidDebounce(value: unknown): value is number;
|
|
25
|
+
export declare const isValidThrottle: typeof isValidDebounce;
|
|
26
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc,EAAG,WAAoB,CAAC;AACnD,eAAO,MAAM,gBAAgB,EAAG,UAAmB,CAAC;AACpD,eAAO,MAAM,gBAAgB,EAAG,UAAmB,CAAC;AAEpD,MAAM,MAAM,aAAa,GAAG,OAAO,cAAc,CAAC;AAClD,MAAM,MAAM,eAAe,GAAG,OAAO,gBAAgB,CAAC;AACtD,MAAM,MAAM,eAAe,GAAG,OAAO,gBAAgB,CAAC;AAEtD,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG;IAC1D,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC;IACvB,CAAC,gBAAgB,CAAC,CAAC,EAAE,MAAM,CAAC;IAC5B,CAAC,gBAAgB,CAAC,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,QAAQ,EAAE,MAAM,GACf,MAAM,CAYR;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAO/D;AAED,eAAO,MAAM,eAAe,wBAAkB,CAAC"}
|
package/dist/handler.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Shared marker property names attached to event handler functions created by
|
|
2
|
+
// `vdom.tsx::createEventHandler`. Centralizing these strings keeps `components.tsx`
|
|
3
|
+
// and `vdom.tsx` in sync without relying on ad-hoc property names.
|
|
4
|
+
export const HANDLER_MARKER = "isHandler";
|
|
5
|
+
export const HANDLER_DEBOUNCE = "debounce";
|
|
6
|
+
export const HANDLER_THROTTLE = "throttle";
|
|
7
|
+
/**
|
|
8
|
+
* Returns the debounce value (in milliseconds) to use as the default for a user
|
|
9
|
+
* input element when no user input has been recorded yet. Uses the maximum
|
|
10
|
+
* debounce among the element's tagged handlers, falling back to the global
|
|
11
|
+
* default if none of the handlers specify one.
|
|
12
|
+
*/
|
|
13
|
+
export function getInitialDebounce(props, fallback) {
|
|
14
|
+
let max = 0;
|
|
15
|
+
for (const value of Object.values(props)) {
|
|
16
|
+
if (typeof value !== "function") {
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
const candidate = value[HANDLER_DEBOUNCE];
|
|
20
|
+
if (typeof candidate === "number" && candidate > max) {
|
|
21
|
+
max = candidate;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return max > 0 ? max : fallback;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Returns true when the given value is a finite, non-negative integer.
|
|
28
|
+
* Used to validate debounce/throttle values arriving over the wire from the
|
|
29
|
+
* Python layout.
|
|
30
|
+
*/
|
|
31
|
+
export function isValidDebounce(value) {
|
|
32
|
+
return (typeof value === "number" &&
|
|
33
|
+
Number.isFinite(value) &&
|
|
34
|
+
Number.isInteger(value) &&
|
|
35
|
+
value >= 0);
|
|
36
|
+
}
|
|
37
|
+
export const isValidThrottle = isValidDebounce;
|
|
38
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,oFAAoF;AACpF,mEAAmE;AAEnE,MAAM,CAAC,MAAM,cAAc,GAAG,WAAoB,CAAC;AACnD,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAmB,CAAC;AACpD,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAmB,CAAC;AAYpD;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAA8B,EAC9B,QAAgB;IAEhB,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACzC,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;YAChC,SAAS;QACX,CAAC;QACD,MAAM,SAAS,GAAI,KAA4B,CAAC,gBAAgB,CAAC,CAAC;QAClE,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,GAAG,GAAG,EAAE,CAAC;YACrD,GAAG,GAAG,SAAS,CAAC;QAClB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QACtB,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;QACvB,KAAK,IAAI,CAAC,CACX,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,eAAe,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,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/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,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/mount.d.ts.map
CHANGED
|
@@ -1 +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,
|
|
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,QA+B7C"}
|
package/dist/mount.js
CHANGED
|
@@ -8,9 +8,9 @@ export function mountReactPy(props) {
|
|
|
8
8
|
const wsOrigin = `${wsProtocol}//${window.location.host}`;
|
|
9
9
|
const componentUrl = new URL(`${wsOrigin}${props.pathPrefix}${props.componentPath || ""}`);
|
|
10
10
|
// Embed the initial HTTP path into the WebSocket URL
|
|
11
|
-
componentUrl.searchParams.append("
|
|
11
|
+
componentUrl.searchParams.append("path", window.location.pathname);
|
|
12
12
|
if (window.location.search) {
|
|
13
|
-
componentUrl.searchParams.append("
|
|
13
|
+
componentUrl.searchParams.append("qs", window.location.search);
|
|
14
14
|
}
|
|
15
15
|
// Configure a new ReactPy client
|
|
16
16
|
const client = new ReactPyClient({
|
package/dist/mount.js.map
CHANGED
|
@@ -1 +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,
|
|
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,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACnE,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC3B,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjE,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
CHANGED
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAI5C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG;IAC7C,GAAG,EAAE,GAAG,CAAC;IACT,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,SAAS,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAChD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,YAAY,EAAE,GAAG,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,EAAE,WAAW,CAAC;IAClB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,YAAY,EAAE,WAAW,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,YAAY,EAAE,WAAW,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC,CAAC;AAIF,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAAC;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,CAAC,CAAC;AAErE,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACvC,QAAQ,CAAC,EAAE,CAAC,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,CAAA;KAAE,CAAC;IAC3D,gBAAgB,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAC7C,YAAY,CAAC,EAAE,uBAAuB,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/vdom.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ReactPyVdom, ReactPyVdomImportSource, BindImportSource } from "./types";
|
|
2
1
|
import type { ReactPyClient } from "./client";
|
|
2
|
+
import type { BindImportSource, ReactPyVdom, ReactPyVdomImportSource } from "./types";
|
|
3
3
|
export declare function loadImportSource(vdomImportSource: ReactPyVdomImportSource, client: ReactPyClient): Promise<BindImportSource>;
|
|
4
4
|
export declare function createChildren<Child>(model: ReactPyVdom, createChild: (child: ReactPyVdom) => Child): (Child | string)[];
|
|
5
5
|
export declare function createAttributes(model: ReactPyVdom, client: ReactPyClient): {
|
package/dist/vdom.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vdom.d.ts","sourceRoot":"","sources":["../src/vdom.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vdom.d.ts","sourceRoot":"","sources":["../src/vdom.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,KAAK,EACV,gBAAgB,EAIhB,WAAW,EAEX,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAEjB,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
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import eventToObject from "event-to-object";
|
|
2
2
|
import { Fragment } from "preact";
|
|
3
|
+
import { HANDLER_DEBOUNCE, HANDLER_MARKER, HANDLER_THROTTLE, isValidDebounce, isValidThrottle, } from "./handler";
|
|
3
4
|
import { infer_bind_from_environment } from "./bind";
|
|
4
5
|
import log from "./logger";
|
|
5
6
|
export async function loadImportSource(vdomImportSource, client) {
|
|
@@ -129,7 +130,7 @@ export function createAttributes(model, client) {
|
|
|
129
130
|
...Object.fromEntries(Object.entries(model.inlineJavaScript || {}).map(([name, inlineJavaScript]) => createInlineJavaScript(name, inlineJavaScript))),
|
|
130
131
|
}));
|
|
131
132
|
}
|
|
132
|
-
function createEventHandler(client, name, { target, preventDefault, stopPropagation }) {
|
|
133
|
+
function createEventHandler(client, name, { target, preventDefault, stopPropagation, debounce, throttle, }) {
|
|
133
134
|
const eventHandler = function (...args) {
|
|
134
135
|
const data = Array.from(args).map((value) => {
|
|
135
136
|
const event = value;
|
|
@@ -149,7 +150,25 @@ function createEventHandler(client, name, { target, preventDefault, stopPropagat
|
|
|
149
150
|
});
|
|
150
151
|
client.sendMessage({ type: "layout-event", data, target });
|
|
151
152
|
};
|
|
152
|
-
eventHandler
|
|
153
|
+
eventHandler[HANDLER_MARKER] = true;
|
|
154
|
+
if (debounce !== undefined) {
|
|
155
|
+
if (!isValidDebounce(debounce)) {
|
|
156
|
+
log.warn(`Ignoring invalid debounce value ${JSON.stringify(debounce)} ` +
|
|
157
|
+
`on event handler "${name}": expected a non-negative integer.`);
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
eventHandler[HANDLER_DEBOUNCE] = debounce;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (throttle !== undefined) {
|
|
164
|
+
if (!isValidThrottle(throttle)) {
|
|
165
|
+
log.warn(`Ignoring invalid throttle value ${JSON.stringify(throttle)} ` +
|
|
166
|
+
`on event handler "${name}": expected a non-negative integer.`);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
eventHandler[HANDLER_THROTTLE] = throttle;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
153
172
|
return [name, eventHandler];
|
|
154
173
|
}
|
|
155
174
|
function createInlineJavaScript(name, inlineJavaScript) {
|
package/dist/vdom.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vdom.js","sourceRoot":"","sources":["../src/vdom.tsx"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"vdom.js","sourceRoot":"","sources":["../src/vdom.tsx"],"names":[],"mappings":"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"}
|
package/dist/websocket.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,SAAS,CAAC;AAgBhE,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,gCAAgC;cAOb,SAAS;EAmDpC;AAED,wBAAgB,YAAY,CAC1B,eAAe,EAAE,MAAM,EACvB,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,GAClB,MAAM,CAOR"}
|
package/dist/websocket.js
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import log from "./logger";
|
|
2
|
+
function syncBrowserLocation(url) {
|
|
3
|
+
// The window will always have a HTTP path, so ReactPy should always be aware of it.
|
|
4
|
+
url.searchParams.set("path", window.location.pathname);
|
|
5
|
+
if (window.location.search) {
|
|
6
|
+
// Set the query string parameter if the HTTP location has a query string.
|
|
7
|
+
url.searchParams.set("qs", window.location.search);
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
// Remove any existing (potentially stale) query string parameter if the current location doesn't have one
|
|
11
|
+
url.searchParams.delete("qs");
|
|
12
|
+
}
|
|
13
|
+
}
|
|
2
14
|
export function createReconnectingWebSocket(props) {
|
|
3
15
|
const { interval, maxInterval, maxRetries, backoffMultiplier } = props;
|
|
4
16
|
let retries = 0;
|
|
@@ -10,6 +22,7 @@ export function createReconnectingWebSocket(props) {
|
|
|
10
22
|
if (closed) {
|
|
11
23
|
return;
|
|
12
24
|
}
|
|
25
|
+
syncBrowserLocation(props.url);
|
|
13
26
|
socket.current = new WebSocket(props.url);
|
|
14
27
|
socket.current.onopen = () => {
|
|
15
28
|
everConnected = true;
|
package/dist/websocket.js.map
CHANGED
|
@@ -1 +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"}
|
|
1
|
+
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/bind.tsx
CHANGED
|
@@ -8,9 +8,8 @@ export async function infer_bind_from_environment() {
|
|
|
8
8
|
const ReactDOM = await import("react-dom/client");
|
|
9
9
|
return (node: HTMLElement) => reactjs_bind(node, React, ReactDOM);
|
|
10
10
|
} catch {
|
|
11
|
-
console.
|
|
12
|
-
"
|
|
13
|
-
Your JavaScript components may not work as expected!",
|
|
11
|
+
console.debug(
|
|
12
|
+
"ReactPy will render JavaScript components using internal bindings for 'react'.",
|
|
14
13
|
);
|
|
15
14
|
return (node: HTMLElement) => local_preact_bind(node);
|
|
16
15
|
}
|
package/src/client.ts
CHANGED
|
@@ -59,6 +59,7 @@ export class ReactPyClient
|
|
|
59
59
|
urls: ReactPyUrls;
|
|
60
60
|
socket: { current?: WebSocket };
|
|
61
61
|
mountElement: HTMLElement;
|
|
62
|
+
private readonly messageQueue: any[] = [];
|
|
62
63
|
|
|
63
64
|
constructor(props: GenericReactPyClientProps) {
|
|
64
65
|
super();
|
|
@@ -69,12 +70,24 @@ export class ReactPyClient
|
|
|
69
70
|
url: this.urls.componentUrl,
|
|
70
71
|
readyPromise: this.ready,
|
|
71
72
|
...props.reconnectOptions,
|
|
73
|
+
onOpen: () => {
|
|
74
|
+
while (this.messageQueue.length > 0) {
|
|
75
|
+
this.sendMessage(this.messageQueue.shift());
|
|
76
|
+
}
|
|
77
|
+
},
|
|
72
78
|
onMessage: async ({ data }) => this.handleIncoming(JSON.parse(data)),
|
|
73
79
|
});
|
|
74
80
|
}
|
|
75
81
|
|
|
76
82
|
sendMessage(message: any): void {
|
|
77
|
-
|
|
83
|
+
if (
|
|
84
|
+
this.socket.current &&
|
|
85
|
+
this.socket.current.readyState === WebSocket.OPEN
|
|
86
|
+
) {
|
|
87
|
+
this.socket.current.send(JSON.stringify(message));
|
|
88
|
+
} else {
|
|
89
|
+
this.messageQueue.push(message);
|
|
90
|
+
}
|
|
78
91
|
}
|
|
79
92
|
|
|
80
93
|
loadModule(moduleName: string): Promise<ReactPyModule> {
|
package/src/components.tsx
CHANGED
|
@@ -8,6 +8,14 @@ import {
|
|
|
8
8
|
type TargetedEvent,
|
|
9
9
|
} from "preact";
|
|
10
10
|
import { useContext, useEffect, useRef, useState } from "preact/hooks";
|
|
11
|
+
import {
|
|
12
|
+
HANDLER_DEBOUNCE,
|
|
13
|
+
HANDLER_MARKER,
|
|
14
|
+
HANDLER_THROTTLE,
|
|
15
|
+
getInitialDebounce,
|
|
16
|
+
isValidDebounce,
|
|
17
|
+
type TaggedEventHandler,
|
|
18
|
+
} from "./handler";
|
|
11
19
|
import type {
|
|
12
20
|
ImportSourceBinding,
|
|
13
21
|
ReactPyComponent,
|
|
@@ -18,6 +26,108 @@ import type { ReactPyClient } from "./client";
|
|
|
18
26
|
|
|
19
27
|
const ClientContext = createContext<ReactPyClient>(null as any);
|
|
20
28
|
|
|
29
|
+
// Built-in default debounce (ms) used by user-input elements (``<input>``,
|
|
30
|
+
// ``<select>``, ``<textarea>``) when no per-handler ``debounce`` is set.
|
|
31
|
+
// Non-input elements default to 0 ms (no debounce) — set ``debounce`` or
|
|
32
|
+
// ``throttle`` explicitly on the handler if you need either behavior.
|
|
33
|
+
const DEFAULT_INPUT_DEBOUNCE_MS = 200;
|
|
34
|
+
const DEFAULT_NON_INPUT_DEBOUNCE_MS = 0;
|
|
35
|
+
|
|
36
|
+
const USER_INPUT_TAGS = new Set(["input", "select", "textarea"]);
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Return the built-in default debounce (ms) for an element type.
|
|
40
|
+
* Inputs default to 200 ms to preserve text-input coherency against
|
|
41
|
+
* server-driven ``value`` updates; all other elements default to 0 ms.
|
|
42
|
+
*/
|
|
43
|
+
export function getDefaultDebounceMs(tagName: string): number {
|
|
44
|
+
return USER_INPUT_TAGS.has(tagName)
|
|
45
|
+
? DEFAULT_INPUT_DEBOUNCE_MS
|
|
46
|
+
: DEFAULT_NON_INPUT_DEBOUNCE_MS;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
type UserInputTarget =
|
|
50
|
+
| HTMLInputElement
|
|
51
|
+
| HTMLSelectElement
|
|
52
|
+
| HTMLTextAreaElement;
|
|
53
|
+
|
|
54
|
+
function trackUserInput(
|
|
55
|
+
event: TargetedEvent<any>,
|
|
56
|
+
setValue: (value: any) => void,
|
|
57
|
+
lastUserValue: MutableRefObject<any>,
|
|
58
|
+
lastChangeTime: MutableRefObject<number>,
|
|
59
|
+
lastInputDebounce: MutableRefObject<number>,
|
|
60
|
+
debounce: number,
|
|
61
|
+
): void {
|
|
62
|
+
if (!event.target) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const newValue = (event.target as UserInputTarget).value;
|
|
67
|
+
setValue(newValue);
|
|
68
|
+
lastUserValue.current = newValue;
|
|
69
|
+
lastChangeTime.current = Date.now();
|
|
70
|
+
lastInputDebounce.current = debounce;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Wrap ``handler`` so its outgoing call is throttled to at most once per
|
|
75
|
+
* ``intervalMs`` milliseconds. Subsequent calls inside the window are
|
|
76
|
+
* collapsed and the trailing call (with the most recent arguments) fires
|
|
77
|
+
* once the window expires.
|
|
78
|
+
*
|
|
79
|
+
* Returns the original handler unchanged when ``intervalMs`` is missing or
|
|
80
|
+
* invalid.
|
|
81
|
+
*/
|
|
82
|
+
function throttleHandler(
|
|
83
|
+
handler: TaggedEventHandler,
|
|
84
|
+
intervalMs: number,
|
|
85
|
+
): TaggedEventHandler {
|
|
86
|
+
if (!isValidDebounce(intervalMs)) {
|
|
87
|
+
return handler;
|
|
88
|
+
}
|
|
89
|
+
let pendingArgs: any[] | null = null;
|
|
90
|
+
let timer: number | null = null;
|
|
91
|
+
let lastFireTime = 0;
|
|
92
|
+
|
|
93
|
+
const wrapped = function (...args: any[]) {
|
|
94
|
+
const now = Date.now();
|
|
95
|
+
const elapsed = now - lastFireTime;
|
|
96
|
+
if (elapsed >= intervalMs) {
|
|
97
|
+
// Leading edge: fire immediately, then start a cooldown.
|
|
98
|
+
lastFireTime = now;
|
|
99
|
+
(handler as (...a: any[]) => void)(...args);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
// Trailing edge: remember the latest args and schedule a fire at the
|
|
103
|
+
// end of the cooldown so no event is silently dropped.
|
|
104
|
+
pendingArgs = args;
|
|
105
|
+
if (timer === null) {
|
|
106
|
+
timer = window.setTimeout(
|
|
107
|
+
() => {
|
|
108
|
+
timer = null;
|
|
109
|
+
if (pendingArgs !== null) {
|
|
110
|
+
const callArgs = pendingArgs;
|
|
111
|
+
pendingArgs = null;
|
|
112
|
+
lastFireTime = Date.now();
|
|
113
|
+
(handler as (...a: any[]) => void)(...callArgs);
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
Math.max(0, intervalMs - elapsed),
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
} as TaggedEventHandler;
|
|
120
|
+
|
|
121
|
+
// Preserve the tag markers so downstream code can still introspect the
|
|
122
|
+
// wrapped function.
|
|
123
|
+
wrapped[HANDLER_MARKER] = true;
|
|
124
|
+
const debounce = handler[HANDLER_DEBOUNCE];
|
|
125
|
+
if (typeof debounce === "number") {
|
|
126
|
+
wrapped[HANDLER_DEBOUNCE] = debounce;
|
|
127
|
+
}
|
|
128
|
+
return wrapped;
|
|
129
|
+
}
|
|
130
|
+
|
|
21
131
|
export function Layout(props: { client: ReactPyClient }): JSX.Element {
|
|
22
132
|
const currentModel: ReactPyVdom = useState({ tagName: "" })[0];
|
|
23
133
|
const forceUpdate = useForceUpdate();
|
|
@@ -66,12 +176,29 @@ export function Element({ model }: { model: ReactPyVdom }): JSX.Element | null {
|
|
|
66
176
|
|
|
67
177
|
function StandardElement({ model }: { model: ReactPyVdom }) {
|
|
68
178
|
const client = useContext(ClientContext);
|
|
179
|
+
const attrs = createAttributes(model, client);
|
|
180
|
+
// Apply the throttle wrapper to tagged handlers. ``debounce`` (server-→
|
|
181
|
+
// client value reconciliation) only applies to user-input elements, so
|
|
182
|
+
// it's intentionally ignored here; ``throttle`` works everywhere.
|
|
183
|
+
for (const [name, prop] of Object.entries(attrs)) {
|
|
184
|
+
if (typeof prop !== "function") {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
const handler = prop as TaggedEventHandler;
|
|
188
|
+
if (!handler[HANDLER_MARKER]) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
const throttle = handler[HANDLER_THROTTLE];
|
|
192
|
+
if (isValidDebounce(throttle)) {
|
|
193
|
+
attrs[name] = throttleHandler(handler, throttle as number);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
69
196
|
// Use createElement here to avoid warning about variable numbers of children not
|
|
70
197
|
// having keys. Warning about this must now be the responsibility of the client
|
|
71
198
|
// providing the models instead of the client rendering them.
|
|
72
199
|
return createElement(
|
|
73
200
|
model.tagName === "" ? Fragment : model.tagName,
|
|
74
|
-
|
|
201
|
+
attrs,
|
|
75
202
|
...createChildren(model, (child) => {
|
|
76
203
|
return <Element model={child} key={child.attributes?.key} />;
|
|
77
204
|
}),
|
|
@@ -82,19 +209,77 @@ function UserInputElement({ model }: { model: ReactPyVdom }): JSX.Element {
|
|
|
82
209
|
const client = useContext(ClientContext);
|
|
83
210
|
const props = createAttributes(model, client);
|
|
84
211
|
const [value, setValue] = useState(props.value);
|
|
212
|
+
const lastUserValue = useRef(props.value);
|
|
213
|
+
const lastChangeTime = useRef(0);
|
|
214
|
+
// Seed the debounce window from the handlers themselves when possible,
|
|
215
|
+
// otherwise fall back to the per-tagName built-in default (200 ms for
|
|
216
|
+
// user-input tags, 0 ms elsewhere). This ensures the very first
|
|
217
|
+
// server-driven update already respects the configured debounce.
|
|
218
|
+
const lastInputDebounce = useRef(
|
|
219
|
+
getInitialDebounce(props, getDefaultDebounceMs(model.tagName)),
|
|
220
|
+
);
|
|
221
|
+
const reconcileTimeout = useRef<number | null>(null);
|
|
85
222
|
|
|
86
223
|
// honor changes to value from the client via props
|
|
87
|
-
useEffect(() =>
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
224
|
+
useEffect(() => {
|
|
225
|
+
const reconcileValue = () => {
|
|
226
|
+
// If the new prop value matches what we last sent, we are in sync.
|
|
227
|
+
// If it differs, wait until the debounce window expires before applying it.
|
|
228
|
+
const elapsed = Date.now() - lastChangeTime.current;
|
|
229
|
+
if (
|
|
230
|
+
props.value === lastUserValue.current ||
|
|
231
|
+
elapsed >= lastInputDebounce.current
|
|
232
|
+
) {
|
|
233
|
+
reconcileTimeout.current = null;
|
|
234
|
+
setValue(props.value);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
reconcileTimeout.current = window.setTimeout(
|
|
239
|
+
reconcileValue,
|
|
240
|
+
Math.max(0, lastInputDebounce.current - elapsed),
|
|
241
|
+
);
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
reconcileValue();
|
|
245
|
+
|
|
246
|
+
return () => {
|
|
247
|
+
if (reconcileTimeout.current !== null) {
|
|
248
|
+
window.clearTimeout(reconcileTimeout.current);
|
|
249
|
+
reconcileTimeout.current = null;
|
|
95
250
|
}
|
|
96
|
-
|
|
97
|
-
|
|
251
|
+
};
|
|
252
|
+
}, [props.value]);
|
|
253
|
+
|
|
254
|
+
for (const [name, prop] of Object.entries(props)) {
|
|
255
|
+
if (typeof prop !== "function") {
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const givenHandler = prop as TaggedEventHandler;
|
|
260
|
+
if (!givenHandler[HANDLER_MARKER]) {
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const handlerDebounce = givenHandler[HANDLER_DEBOUNCE];
|
|
265
|
+
const effectiveDebounce = isValidDebounce(handlerDebounce)
|
|
266
|
+
? handlerDebounce
|
|
267
|
+
: getDefaultDebounceMs(model.tagName);
|
|
268
|
+
|
|
269
|
+
const throttled = isValidDebounce(givenHandler[HANDLER_THROTTLE])
|
|
270
|
+
? throttleHandler(givenHandler, givenHandler[HANDLER_THROTTLE] as number)
|
|
271
|
+
: givenHandler;
|
|
272
|
+
|
|
273
|
+
props[name] = (event: TargetedEvent<any>) => {
|
|
274
|
+
trackUserInput(
|
|
275
|
+
event,
|
|
276
|
+
setValue,
|
|
277
|
+
lastUserValue,
|
|
278
|
+
lastChangeTime,
|
|
279
|
+
lastInputDebounce,
|
|
280
|
+
effectiveDebounce,
|
|
281
|
+
);
|
|
282
|
+
throttled(event);
|
|
98
283
|
};
|
|
99
284
|
}
|
|
100
285
|
|
package/src/handler.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Shared marker property names attached to event handler functions created by
|
|
2
|
+
// `vdom.tsx::createEventHandler`. Centralizing these strings keeps `components.tsx`
|
|
3
|
+
// and `vdom.tsx` in sync without relying on ad-hoc property names.
|
|
4
|
+
|
|
5
|
+
export const HANDLER_MARKER = "isHandler" as const;
|
|
6
|
+
export const HANDLER_DEBOUNCE = "debounce" as const;
|
|
7
|
+
export const HANDLER_THROTTLE = "throttle" as const;
|
|
8
|
+
|
|
9
|
+
export type HandlerMarker = typeof HANDLER_MARKER;
|
|
10
|
+
export type HandlerDebounce = typeof HANDLER_DEBOUNCE;
|
|
11
|
+
export type HandlerThrottle = typeof HANDLER_THROTTLE;
|
|
12
|
+
|
|
13
|
+
export type TaggedEventHandler = ((event: Event) => void) & {
|
|
14
|
+
[HANDLER_MARKER]: true;
|
|
15
|
+
[HANDLER_DEBOUNCE]?: number;
|
|
16
|
+
[HANDLER_THROTTLE]?: number;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Returns the debounce value (in milliseconds) to use as the default for a user
|
|
21
|
+
* input element when no user input has been recorded yet. Uses the maximum
|
|
22
|
+
* debounce among the element's tagged handlers, falling back to the global
|
|
23
|
+
* default if none of the handlers specify one.
|
|
24
|
+
*/
|
|
25
|
+
export function getInitialDebounce(
|
|
26
|
+
props: Record<string, unknown>,
|
|
27
|
+
fallback: number,
|
|
28
|
+
): number {
|
|
29
|
+
let max = 0;
|
|
30
|
+
for (const value of Object.values(props)) {
|
|
31
|
+
if (typeof value !== "function") {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const candidate = (value as TaggedEventHandler)[HANDLER_DEBOUNCE];
|
|
35
|
+
if (typeof candidate === "number" && candidate > max) {
|
|
36
|
+
max = candidate;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return max > 0 ? max : fallback;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Returns true when the given value is a finite, non-negative integer.
|
|
44
|
+
* Used to validate debounce/throttle values arriving over the wire from the
|
|
45
|
+
* Python layout.
|
|
46
|
+
*/
|
|
47
|
+
export function isValidDebounce(value: unknown): value is number {
|
|
48
|
+
return (
|
|
49
|
+
typeof value === "number" &&
|
|
50
|
+
Number.isFinite(value) &&
|
|
51
|
+
Number.isInteger(value) &&
|
|
52
|
+
value >= 0
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const isValidThrottle = isValidDebounce;
|
package/src/index.ts
CHANGED
package/src/mount.tsx
CHANGED
|
@@ -12,12 +12,9 @@ export function mountReactPy(props: MountProps) {
|
|
|
12
12
|
);
|
|
13
13
|
|
|
14
14
|
// Embed the initial HTTP path into the WebSocket URL
|
|
15
|
-
componentUrl.searchParams.append("
|
|
15
|
+
componentUrl.searchParams.append("path", window.location.pathname);
|
|
16
16
|
if (window.location.search) {
|
|
17
|
-
componentUrl.searchParams.append(
|
|
18
|
-
"http_query_string",
|
|
19
|
-
window.location.search,
|
|
20
|
-
);
|
|
17
|
+
componentUrl.searchParams.append("qs", window.location.search);
|
|
21
18
|
}
|
|
22
19
|
|
|
23
20
|
// Configure a new ReactPy client
|
package/src/types.ts
CHANGED
package/src/vdom.tsx
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import eventToObject from "event-to-object";
|
|
2
2
|
import { Fragment } from "preact";
|
|
3
|
+
import {
|
|
4
|
+
HANDLER_DEBOUNCE,
|
|
5
|
+
HANDLER_MARKER,
|
|
6
|
+
HANDLER_THROTTLE,
|
|
7
|
+
isValidDebounce,
|
|
8
|
+
isValidThrottle,
|
|
9
|
+
type TaggedEventHandler,
|
|
10
|
+
} from "./handler";
|
|
11
|
+
import { infer_bind_from_environment } from "./bind";
|
|
12
|
+
import log from "./logger";
|
|
13
|
+
import type { ReactPyClient } from "./client";
|
|
3
14
|
import type {
|
|
4
|
-
ReactPyVdom,
|
|
5
|
-
ReactPyVdomImportSource,
|
|
6
|
-
ReactPyVdomEventHandler,
|
|
7
|
-
ReactPyModule,
|
|
8
15
|
BindImportSource,
|
|
9
|
-
ReactPyModuleBinding,
|
|
10
16
|
ImportSourceBinding,
|
|
17
|
+
ReactPyModule,
|
|
18
|
+
ReactPyModuleBinding,
|
|
19
|
+
ReactPyVdom,
|
|
20
|
+
ReactPyVdomEventHandler,
|
|
21
|
+
ReactPyVdomImportSource,
|
|
11
22
|
} from "./types";
|
|
12
|
-
import { infer_bind_from_environment } from "./bind";
|
|
13
|
-
import log from "./logger";
|
|
14
|
-
import type { ReactPyClient } from "./client";
|
|
15
23
|
|
|
16
24
|
export async function loadImportSource(
|
|
17
25
|
vdomImportSource: ReactPyVdomImportSource,
|
|
@@ -206,8 +214,14 @@ export function createAttributes(
|
|
|
206
214
|
function createEventHandler(
|
|
207
215
|
client: ReactPyClient,
|
|
208
216
|
name: string,
|
|
209
|
-
{
|
|
210
|
-
|
|
217
|
+
{
|
|
218
|
+
target,
|
|
219
|
+
preventDefault,
|
|
220
|
+
stopPropagation,
|
|
221
|
+
debounce,
|
|
222
|
+
throttle,
|
|
223
|
+
}: ReactPyVdomEventHandler,
|
|
224
|
+
): [string, TaggedEventHandler] {
|
|
211
225
|
const eventHandler = function (...args: any[]) {
|
|
212
226
|
const data = Array.from(args).map((value) => {
|
|
213
227
|
const event = value as Event;
|
|
@@ -226,8 +240,28 @@ function createEventHandler(
|
|
|
226
240
|
}
|
|
227
241
|
});
|
|
228
242
|
client.sendMessage({ type: "layout-event", data, target });
|
|
229
|
-
};
|
|
230
|
-
eventHandler
|
|
243
|
+
} as TaggedEventHandler;
|
|
244
|
+
eventHandler[HANDLER_MARKER] = true;
|
|
245
|
+
if (debounce !== undefined) {
|
|
246
|
+
if (!isValidDebounce(debounce)) {
|
|
247
|
+
log.warn(
|
|
248
|
+
`Ignoring invalid debounce value ${JSON.stringify(debounce)} ` +
|
|
249
|
+
`on event handler "${name}": expected a non-negative integer.`,
|
|
250
|
+
);
|
|
251
|
+
} else {
|
|
252
|
+
eventHandler[HANDLER_DEBOUNCE] = debounce;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (throttle !== undefined) {
|
|
256
|
+
if (!isValidThrottle(throttle)) {
|
|
257
|
+
log.warn(
|
|
258
|
+
`Ignoring invalid throttle value ${JSON.stringify(throttle)} ` +
|
|
259
|
+
`on event handler "${name}": expected a non-negative integer.`,
|
|
260
|
+
);
|
|
261
|
+
} else {
|
|
262
|
+
eventHandler[HANDLER_THROTTLE] = throttle;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
231
265
|
return [name, eventHandler];
|
|
232
266
|
}
|
|
233
267
|
|
package/src/websocket.ts
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
import type { CreateReconnectingWebSocketProps } from "./types";
|
|
2
2
|
import log from "./logger";
|
|
3
3
|
|
|
4
|
+
function syncBrowserLocation(url: URL): void {
|
|
5
|
+
// The window will always have a HTTP path, so ReactPy should always be aware of it.
|
|
6
|
+
url.searchParams.set("path", window.location.pathname);
|
|
7
|
+
|
|
8
|
+
if (window.location.search) {
|
|
9
|
+
// Set the query string parameter if the HTTP location has a query string.
|
|
10
|
+
url.searchParams.set("qs", window.location.search);
|
|
11
|
+
} else {
|
|
12
|
+
// Remove any existing (potentially stale) query string parameter if the current location doesn't have one
|
|
13
|
+
url.searchParams.delete("qs");
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
4
17
|
export function createReconnectingWebSocket(
|
|
5
18
|
props: CreateReconnectingWebSocketProps,
|
|
6
19
|
) {
|
|
@@ -15,6 +28,7 @@ export function createReconnectingWebSocket(
|
|
|
15
28
|
if (closed) {
|
|
16
29
|
return;
|
|
17
30
|
}
|
|
31
|
+
syncBrowserLocation(props.url);
|
|
18
32
|
socket.current = new WebSocket(props.url);
|
|
19
33
|
socket.current.onopen = () => {
|
|
20
34
|
everConnected = true;
|