@reactpy/client 0.3.2 → 1.0.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.
Files changed (58) hide show
  1. package/dist/client.d.ts +29 -0
  2. package/dist/client.d.ts.map +1 -0
  3. package/dist/client.js +60 -0
  4. package/dist/client.js.map +1 -0
  5. package/dist/components.d.ts +3 -4
  6. package/dist/components.d.ts.map +1 -1
  7. package/dist/components.js +38 -37
  8. package/dist/components.js.map +1 -1
  9. package/dist/index.d.ts +7 -3
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +7 -3
  12. package/dist/index.js.map +1 -1
  13. package/dist/logger.d.ts +1 -0
  14. package/dist/logger.d.ts.map +1 -1
  15. package/dist/logger.js +1 -0
  16. package/dist/logger.js.map +1 -1
  17. package/dist/mount.d.ts +2 -2
  18. package/dist/mount.d.ts.map +1 -1
  19. package/dist/mount.js +29 -4
  20. package/dist/mount.js.map +1 -1
  21. package/dist/types.d.ts +126 -0
  22. package/dist/types.d.ts.map +1 -0
  23. package/dist/types.js +1 -0
  24. package/dist/types.js.map +1 -0
  25. package/dist/vdom.d.ts +8 -0
  26. package/dist/vdom.d.ts.map +1 -0
  27. package/dist/vdom.js +174 -0
  28. package/dist/vdom.js.map +1 -0
  29. package/dist/websocket.d.ts +6 -0
  30. package/dist/websocket.d.ts.map +1 -0
  31. package/dist/websocket.js +57 -0
  32. package/dist/websocket.js.map +1 -0
  33. package/package.json +23 -22
  34. package/src/client.ts +83 -0
  35. package/src/components.tsx +40 -46
  36. package/src/index.ts +7 -3
  37. package/src/logger.ts +1 -0
  38. package/src/mount.tsx +37 -5
  39. package/src/types.ts +152 -0
  40. package/src/vdom.tsx +256 -0
  41. package/src/websocket.ts +75 -0
  42. package/tsconfig.json +3 -3
  43. package/tsconfig.tsbuildinfo +1 -0
  44. package/dist/messages.d.ts +0 -15
  45. package/dist/messages.d.ts.map +0 -1
  46. package/dist/messages.js +0 -2
  47. package/dist/messages.js.map +0 -1
  48. package/dist/reactpy-client.d.ts +0 -94
  49. package/dist/reactpy-client.d.ts.map +0 -1
  50. package/dist/reactpy-client.js +0 -128
  51. package/dist/reactpy-client.js.map +0 -1
  52. package/dist/reactpy-vdom.d.ts +0 -54
  53. package/dist/reactpy-vdom.d.ts.map +0 -1
  54. package/dist/reactpy-vdom.js +0 -141
  55. package/dist/reactpy-vdom.js.map +0 -1
  56. package/src/messages.ts +0 -17
  57. package/src/reactpy-client.ts +0 -264
  58. package/src/reactpy-vdom.tsx +0 -261
@@ -1,94 +0,0 @@
1
- import { ReactPyModule } from "./reactpy-vdom";
2
- /**
3
- * A client for communicating with a ReactPy server.
4
- */
5
- export interface ReactPyClient {
6
- /**
7
- * Register a handler for a message type.
8
- *
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.
14
- */
15
- onMessage(type: string, handler: (message: any) => void): () => void;
16
- /**
17
- * Send a message to the server.
18
- *
19
- * @param message The message to send. Messages must have a `type` property.
20
- */
21
- sendMessage(message: any): void;
22
- /**
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.
26
- */
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>;
37
- /**
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.
43
- */
44
- protected handleIncoming(message: any): void;
45
- }
46
- export type SimpleReactPyClientProps = {
47
- serverLocation?: LocationProps;
48
- reconnectOptions?: ReconnectProps;
49
- };
50
- /**
51
- * The location of the server.
52
- *
53
- * This is used to determine the location of the server's API endpoints. All endpoints
54
- * are expected to be found at the base URL, with the following paths:
55
- *
56
- * - `_reactpy/stream/${route}${query}`: The websocket endpoint for the stream.
57
- * - `_reactpy/modules`: The directory containing the dynamically loaded modules.
58
- * - `_reactpy/assets`: The directory containing the static assets.
59
- */
60
- type LocationProps = {
61
- /**
62
- * The base URL of the server.
63
- *
64
- * @default - document.location.origin
65
- */
66
- url: string;
67
- /**
68
- * The route to the page being rendered.
69
- *
70
- * @default - document.location.pathname
71
- */
72
- route: string;
73
- /**
74
- * The query string of the page being rendered.
75
- *
76
- * @default - document.location.search
77
- */
78
- query: string;
79
- };
80
- type ReconnectProps = {
81
- maxInterval?: number;
82
- maxRetries?: number;
83
- backoffRate?: number;
84
- intervalJitter?: number;
85
- };
86
- export declare class SimpleReactPyClient extends BaseReactPyClient implements ReactPyClient {
87
- private readonly urls;
88
- private readonly socket;
89
- constructor(props: SimpleReactPyClientProps);
90
- sendMessage(message: any): void;
91
- loadModule(moduleName: string): Promise<ReactPyModule>;
92
- }
93
- export {};
94
- //# sourceMappingURL=reactpy-client.d.ts.map
@@ -1 +0,0 @@
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"}
@@ -1,128 +0,0 @@
1
- import logger from "./logger";
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 {
38
- urls;
39
- socket;
40
- constructor(props) {
41
- super();
42
- this.urls = getServerUrls(props.serverLocation || {
43
- url: document.location.origin,
44
- route: document.location.pathname,
45
- query: document.location.search,
46
- });
47
- this.socket = createReconnectingWebSocket({
48
- readyPromise: this.ready,
49
- url: this.urls.stream,
50
- onMessage: async ({ data }) => this.handleIncoming(JSON.parse(data)),
51
- ...props.reconnectOptions,
52
- });
53
- }
54
- sendMessage(message) {
55
- this.socket.current?.send(JSON.stringify(message));
56
- }
57
- loadModule(moduleName) {
58
- return import(`${this.urls.modules}/${moduleName}`);
59
- }
60
- }
61
- function getServerUrls(props) {
62
- const base = new URL(`${props.url || document.location.origin}/_reactpy`);
63
- const modules = `${base}/modules`;
64
- const assets = `${base}/assets`;
65
- const streamProtocol = `ws${base.protocol === "https:" ? "s" : ""}`;
66
- const streamPath = rtrim(`${base.pathname}/stream${props.route || ""}`, "/");
67
- const stream = `${streamProtocol}://${base.host}${streamPath}${props.query}`;
68
- return { base, modules, assets, stream };
69
- }
70
- function createReconnectingWebSocket(props) {
71
- const { maxInterval = 60000, maxRetries = 50, backoffRate = 1.1, intervalJitter = 0.1, } = props;
72
- const startInterval = 750;
73
- let retries = 0;
74
- let interval = startInterval;
75
- const closed = false;
76
- let everConnected = false;
77
- const socket = {};
78
- const connect = () => {
79
- if (closed) {
80
- return;
81
- }
82
- socket.current = new WebSocket(props.url);
83
- socket.current.onopen = () => {
84
- everConnected = true;
85
- logger.log("client connected");
86
- interval = startInterval;
87
- retries = 0;
88
- if (props.onOpen) {
89
- props.onOpen();
90
- }
91
- };
92
- socket.current.onmessage = props.onMessage;
93
- socket.current.onclose = () => {
94
- if (!everConnected) {
95
- logger.log("failed to connect");
96
- return;
97
- }
98
- logger.log("client disconnected");
99
- if (props.onClose) {
100
- props.onClose();
101
- }
102
- if (retries >= maxRetries) {
103
- return;
104
- }
105
- const thisInterval = addJitter(interval, intervalJitter);
106
- logger.log(`reconnecting in ${(thisInterval / 1000).toPrecision(4)} seconds...`);
107
- setTimeout(connect, thisInterval);
108
- interval = nextInterval(interval, backoffRate, maxInterval);
109
- retries++;
110
- };
111
- };
112
- props.readyPromise.then(() => logger.log("starting client...")).then(connect);
113
- return socket;
114
- }
115
- function nextInterval(currentInterval, backoffRate, maxInterval) {
116
- return Math.min(currentInterval *
117
- // increase interval by backoff rate
118
- backoffRate,
119
- // don't exceed max interval
120
- maxInterval);
121
- }
122
- function addJitter(interval, jitter) {
123
- return interval + (Math.random() * jitter * interval * 2 - jitter * interval);
124
- }
125
- function rtrim(text, trim) {
126
- return text.replace(new RegExp(`${trim}+$`), "");
127
- }
128
- //# sourceMappingURL=reactpy-client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reactpy-client.js","sourceRoot":"","sources":["../src/reactpy-client.ts"],"names":[],"mappings":"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"}
@@ -1,54 +0,0 @@
1
- import { ComponentType } from "react";
2
- import { ReactPyClient } from "./reactpy-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
- export type ReactPyComponent = ComponentType<{
9
- model: ReactPyVdom;
10
- }>;
11
- export type ReactPyVdom = {
12
- tagName: string;
13
- key?: string;
14
- attributes?: {
15
- [key: string]: string;
16
- };
17
- children?: (ReactPyVdom | string)[];
18
- error?: string;
19
- eventHandlers?: {
20
- [key: string]: ReactPyVdomEventHandler;
21
- };
22
- importSource?: ReactPyVdomImportSource;
23
- };
24
- export type ReactPyVdomEventHandler = {
25
- target: string;
26
- preventDefault?: boolean;
27
- stopPropagation?: boolean;
28
- };
29
- export type ReactPyVdomImportSource = {
30
- source: string;
31
- sourceType?: "URL" | "NAME";
32
- fallback?: string | ReactPyVdom;
33
- unmountBeforeUpdate?: boolean;
34
- };
35
- export type ReactPyModule = {
36
- bind: (node: HTMLElement, context: ReactPyModuleBindingContext) => ReactPyModuleBinding;
37
- } & {
38
- [key: string]: any;
39
- };
40
- export type ReactPyModuleBindingContext = {
41
- sendMessage: ReactPyClient["sendMessage"];
42
- onMessage: ReactPyClient["onMessage"];
43
- };
44
- export type ReactPyModuleBinding = {
45
- create: (type: any, props?: any, children?: (any | string | ReactPyVdom)[]) => any;
46
- render: (element: any) => void;
47
- unmount: () => void;
48
- };
49
- export type BindImportSource = (node: HTMLElement) => ImportSourceBinding | null;
50
- export type ImportSourceBinding = {
51
- render: (model: ReactPyVdom) => void;
52
- unmount: () => void;
53
- };
54
- //# sourceMappingURL=reactpy-vdom.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reactpy-vdom.d.ts","sourceRoot":"","sources":["../src/reactpy-vdom.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,wBAAsB,gBAAgB,CACpC,gBAAgB,EAAE,uBAAuB,EACzC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,gBAAgB,CAAC,CA2C3B;AA+DD,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,CAcxB;AA0DD,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,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,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,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;CAC3B,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAChC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,CACJ,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,2BAA2B,KACjC,oBAAoB,CAAC;CAC3B,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,CAAC;AAE3B,MAAM,MAAM,2BAA2B,GAAG;IACxC,WAAW,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IAC1C,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,CACN,IAAI,EAAE,GAAG,EACT,KAAK,CAAC,EAAE,GAAG,EACX,QAAQ,CAAC,EAAE,CAAC,GAAG,GAAG,MAAM,GAAG,WAAW,CAAC,EAAE,KACtC,GAAG,CAAC;IACT,MAAM,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAC7B,IAAI,EAAE,WAAW,KACd,mBAAmB,GAAG,IAAI,CAAC;AAEhC,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACrC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC"}
@@ -1,141 +0,0 @@
1
- import serializeEvent from "event-to-object";
2
- export async function loadImportSource(vdomImportSource, client) {
3
- let module;
4
- if (vdomImportSource.sourceType === "URL") {
5
- module = await import(vdomImportSource.source);
6
- }
7
- else {
8
- module = await client.loadModule(vdomImportSource.source);
9
- }
10
- if (typeof module.bind !== "function") {
11
- throw new Error(`${vdomImportSource.source} did not export a function 'bind'`);
12
- }
13
- return (node) => {
14
- const binding = module.bind(node, {
15
- sendMessage: client.sendMessage,
16
- onMessage: client.onMessage,
17
- });
18
- if (!(typeof binding.create === "function" &&
19
- typeof binding.render === "function" &&
20
- typeof binding.unmount === "function")) {
21
- console.error(`${vdomImportSource.source} returned an impropper binding`);
22
- return null;
23
- }
24
- return {
25
- render: (model) => binding.render(createImportSourceElement({
26
- client,
27
- module,
28
- binding,
29
- model,
30
- currentImportSource: vdomImportSource,
31
- })),
32
- unmount: binding.unmount,
33
- };
34
- };
35
- }
36
- function createImportSourceElement(props) {
37
- let type;
38
- if (props.model.importSource) {
39
- if (!isImportSourceEqual(props.currentImportSource, props.model.importSource)) {
40
- console.error("Parent element import source " +
41
- stringifyImportSource(props.currentImportSource) +
42
- " does not match child's import source " +
43
- stringifyImportSource(props.model.importSource));
44
- return null;
45
- }
46
- else if (!props.module[props.model.tagName]) {
47
- console.error("Module from source " +
48
- stringifyImportSource(props.currentImportSource) +
49
- ` does not export ${props.model.tagName}`);
50
- return null;
51
- }
52
- else {
53
- type = props.module[props.model.tagName];
54
- }
55
- }
56
- else {
57
- type = props.model.tagName;
58
- }
59
- return props.binding.create(type, createAttributes(props.model, props.client), createChildren(props.model, (child) => createImportSourceElement({
60
- ...props,
61
- model: child,
62
- })));
63
- }
64
- function isImportSourceEqual(source1, source2) {
65
- return (source1.source === source2.source &&
66
- source1.sourceType === source2.sourceType);
67
- }
68
- function stringifyImportSource(importSource) {
69
- return JSON.stringify({
70
- source: importSource.source,
71
- sourceType: importSource.sourceType,
72
- });
73
- }
74
- export function createChildren(model, createChild) {
75
- if (!model.children) {
76
- return [];
77
- }
78
- else {
79
- return model.children.map((child) => {
80
- switch (typeof child) {
81
- case "object":
82
- return createChild(child);
83
- case "string":
84
- return child;
85
- }
86
- });
87
- }
88
- }
89
- export function createAttributes(model, client) {
90
- return Object.fromEntries(Object.entries({
91
- // Normal HTML attributes
92
- ...model.attributes,
93
- // Construct event handlers
94
- ...Object.fromEntries(Object.entries(model.eventHandlers || {}).map(([name, handler]) => createEventHandler(client, name, handler))),
95
- // Convert snake_case to camelCase names
96
- }).map(normalizeAttribute));
97
- }
98
- function createEventHandler(client, name, { target, preventDefault, stopPropagation }) {
99
- return [
100
- name,
101
- function (...args) {
102
- const data = Array.from(args).map((value) => {
103
- if (!(typeof value === "object" && value.nativeEvent)) {
104
- return value;
105
- }
106
- const event = value;
107
- if (preventDefault) {
108
- event.preventDefault();
109
- }
110
- if (stopPropagation) {
111
- event.stopPropagation();
112
- }
113
- return serializeEvent(event.nativeEvent);
114
- });
115
- client.sendMessage({ type: "layout-event", data, target });
116
- },
117
- ];
118
- }
119
- function normalizeAttribute([key, value]) {
120
- let normKey = key;
121
- let normValue = value;
122
- if (key === "style" && typeof value === "object") {
123
- normValue = Object.fromEntries(Object.entries(value).map(([k, v]) => [snakeToCamel(k), v]));
124
- }
125
- else if (key.startsWith("data_") ||
126
- key.startsWith("aria_") ||
127
- DASHED_HTML_ATTRS.includes(key)) {
128
- normKey = key.split("_").join("-");
129
- }
130
- else {
131
- normKey = snakeToCamel(key);
132
- }
133
- return [normKey, normValue];
134
- }
135
- function snakeToCamel(str) {
136
- return str.replace(/([_][a-z])/g, (group) => group.toUpperCase().replace("_", ""));
137
- }
138
- // see list of HTML attributes with dashes in them:
139
- // https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes#attribute_list
140
- const DASHED_HTML_ATTRS = ["accept_charset", "http_equiv"];
141
- //# sourceMappingURL=reactpy-vdom.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reactpy-vdom.js","sourceRoot":"","sources":["../src/reactpy-vdom.tsx"],"names":[],"mappings":"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"}
package/src/messages.ts DELETED
@@ -1,17 +0,0 @@
1
- import { ReactPyVdom } from "./reactpy-vdom";
2
-
3
- export type LayoutUpdateMessage = {
4
- type: "layout-update";
5
- path: string;
6
- model: ReactPyVdom;
7
- };
8
-
9
- export type LayoutEventMessage = {
10
- type: "layout-event";
11
- target: string;
12
- data: any;
13
- };
14
-
15
- export type IncomingMessage = LayoutUpdateMessage;
16
- export type OutgoingMessage = LayoutEventMessage;
17
- export type Message = IncomingMessage | OutgoingMessage;