mono-jsx 0.9.1 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -538,6 +538,9 @@ function Counter(this: FC<{ count: number }>, props: { initialCount?: number })
538
538
  // Initialize a signal
539
539
  this.count = props.initialCount ?? 0;
540
540
 
541
+ // or you can use `this.init` to initialize the signals
542
+ this.init({ count: props.initialCount ?? 0 });
543
+
541
544
  return (
542
545
  <div>
543
546
  {/* render signal */}
@@ -551,25 +554,6 @@ function Counter(this: FC<{ count: number }>, props: { initialCount?: number })
551
554
  }
552
555
  ```
553
556
 
554
- You can also use `this.extend` method to extend the signals:
555
-
556
- ```tsx
557
- function Counter(this: FC, props: { initialCount?: number }) {
558
- const counter = this.extend({ count: props.initialCount ?? 0})
559
-
560
- return (
561
- <div>
562
- {/* render signal */}
563
- <span>{counter.count}</span>
564
-
565
- {/* Update signal to trigger re-render */}
566
- <button onClick={() => counter.count--}>-</button>
567
- <button onClick={() => counter.count++}>+</button>
568
- </div>
569
- )
570
- }
571
- ```
572
-
573
557
  ### Using App Signals
574
558
 
575
559
  You can define app signals by adding the `app` prop to the root `<html>` element. The app signals are available in all components via `this.app.<SignalName>`. Changes to the app signals will trigger re-renders in all components that use them:
package/dom/index.mjs CHANGED
@@ -1,5 +1,8 @@
1
1
  // dom/index.ts
2
- import { Store } from "./jsx-runtime.mjs";
2
+ import { createStore } from "./jsx-runtime.mjs";
3
+ var atom = (initValue) => createStore({ value: initValue });
4
+ var store = createStore;
3
5
  export {
4
- Store
6
+ atom,
7
+ store
5
8
  };
@@ -12,6 +12,7 @@ var JSX = {
12
12
  var regexpIsNonDimensional = /^(-|f[lo].*[^se]$|g.{5,}[^ps]$|z|o[pr]|(W.{5})?[lL]i.*(t|mp)$|an|(bo|s).{4}Im|sca|m.{6}[ds]|ta|c.*[st]$|wido|ini)/;
13
13
  var isString = (v) => typeof v === "string";
14
14
  var isFunction = (v) => typeof v === "function";
15
+ var isObject = (v) => typeof v === "object" && v !== null;
15
16
  var isPlainObject = (v) => !!v && (v.constructor === Object || v.constructor === void 0);
16
17
  var toHyphenCase = (k) => k.replace(/[a-z][A-Z]/g, (m) => m.charAt(0) + "-" + m.charAt(1).toLowerCase());
17
18
  var hashCode = (str) => {
@@ -34,10 +35,9 @@ var domEscapeHTML = (text) => {
34
35
  };
35
36
 
36
37
  // symbols.ts
37
- var $fragment = Symbol.for("jsx.fragment");
38
- var $html = Symbol.for("jsx.html");
39
- var $vnode = Symbol.for("jsx.vnode");
40
- var $setup = Symbol.for("mono.setup");
38
+ var $fragment = /* @__PURE__ */ Symbol.for("jsx.fragment");
39
+ var $html = /* @__PURE__ */ Symbol.for("jsx.html");
40
+ var $vnode = /* @__PURE__ */ Symbol.for("jsx.vnode");
41
41
 
42
42
  // dom/render.ts
43
43
  var Reactive = class {
@@ -134,12 +134,13 @@ var InsertMark = class {
134
134
  }
135
135
  };
136
136
  var document2 = globalThis.document;
137
- var $get = Symbol();
138
- var $watch = Symbol();
139
- var $expr = Symbol();
140
- var $slots = Symbol();
141
- var stores = /* @__PURE__ */ new Set();
137
+ var $get = /* @__PURE__ */ Symbol();
138
+ var $watch = /* @__PURE__ */ Symbol();
139
+ var $expr = /* @__PURE__ */ Symbol();
140
+ var $slots = /* @__PURE__ */ Symbol();
141
+ var globalScopes = /* @__PURE__ */ new Set();
142
142
  var isVNode = (v) => Array.isArray(v) && v.length === 3 && v[2] === $vnode;
143
+ var isGetter = (v) => isObject(v) && "value" in v;
143
144
  var createTextNode = (text = "") => document2.createTextNode(text);
144
145
  var createElement = (tag) => document2.createElement(tag);
145
146
  var onAbort = (signal, callback) => signal?.addEventListener("abort", callback);
@@ -156,7 +157,7 @@ var setAttribute = (el, name, value) => {
156
157
  };
157
158
  var call$expr = (scope, ok) => {
158
159
  scope[$expr](ok);
159
- stores.forEach((s) => s[$expr](ok));
160
+ globalScopes.forEach((s) => s[$expr](ok));
160
161
  };
161
162
  var $depsMark;
162
163
  var createScope = (slots, abortSignal) => {
@@ -204,10 +205,8 @@ var createScope = (slots, abortSignal) => {
204
205
  if (get) {
205
206
  target[key2] = new Computed(receiver, get);
206
207
  } else {
207
- if (key2 === "effect") {
208
- if (isFunction(value)) {
209
- receiver.effect(value);
210
- }
208
+ if (key2 === "effect" && isFunction(value)) {
209
+ receiver.effect(value);
211
210
  } else {
212
211
  target[key2] = value;
213
212
  }
@@ -274,10 +273,16 @@ var createScope = (slots, abortSignal) => {
274
273
  };
275
274
  var createStore = (props) => {
276
275
  const scope = createScope().extend(props);
277
- stores.add(scope);
276
+ globalScopes.add(scope);
278
277
  return scope;
279
278
  };
280
279
  var render = (scope, child, root, abortSignal) => {
280
+ if (isGetter(child)) {
281
+ const expr = child[$expr];
282
+ expr?.(true);
283
+ child = child.value;
284
+ expr?.(false);
285
+ }
281
286
  switch (typeof child) {
282
287
  case "boolean":
283
288
  case "undefined":
@@ -709,7 +714,6 @@ HTMLElement.prototype.mount = function(node, aboutSignal) {
709
714
  render(null, node, this, aboutSignal);
710
715
  };
711
716
  Object.assign(globalThis, {
712
- Store: createStore,
713
717
  JSX,
714
718
  html,
715
719
  css: html,
@@ -718,7 +722,7 @@ Object.assign(globalThis, {
718
722
  export {
719
723
  Fragment,
720
724
  JSX,
721
- createStore as Store,
725
+ createStore,
722
726
  html as css,
723
727
  html,
724
728
  html as js,
package/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  // index.ts
2
2
  function buildRoutes(handler) {
3
- const { routes = {} } = handler(Symbol.for("mono.setup"));
3
+ const { routes = {} } = handler(/* @__PURE__ */ Symbol.for("mono.setup"));
4
4
  return monoRoutes(routes, handler);
5
5
  }
6
6
  function monoRoutes(routes, handler) {
package/jsx-runtime.mjs CHANGED
@@ -170,13 +170,13 @@ var escapeHTML = (str) => {
170
170
  };
171
171
 
172
172
  // symbols.ts
173
- var $fragment = Symbol.for("jsx.fragment");
174
- var $html = Symbol.for("jsx.html");
175
- var $vnode = Symbol.for("jsx.vnode");
176
- var $setup = Symbol.for("mono.setup");
173
+ var $fragment = /* @__PURE__ */ Symbol.for("jsx.fragment");
174
+ var $html = /* @__PURE__ */ Symbol.for("jsx.html");
175
+ var $vnode = /* @__PURE__ */ Symbol.for("jsx.vnode");
176
+ var $setup = /* @__PURE__ */ Symbol.for("mono.setup");
177
177
 
178
178
  // version.ts
179
- var VERSION = "0.9.0";
179
+ var VERSION = "0.9.1";
180
180
 
181
181
  // render.ts
182
182
  var FunctionIdGenerator = class extends Map {
@@ -897,6 +897,8 @@ async function renderNode(rc, node, stripSlotProp) {
897
897
  for (const child of node) {
898
898
  await renderNode(rc, child);
899
899
  }
900
+ } else if ("value" in node) {
901
+ await renderNode(rc, node.value);
900
902
  }
901
903
  break;
902
904
  }
@@ -1073,7 +1075,7 @@ function renderAttr(rc, attrName, attrValue, stripSlotProp) {
1073
1075
  console.error("[mono-jsx] Use `ref` outside of a component function");
1074
1076
  } else {
1075
1077
  const refId = rc.fc.refs++;
1076
- const effects = signals[Symbol.for("effects")];
1078
+ const effects = signals[/* @__PURE__ */ Symbol.for("effects")];
1077
1079
  effects.push("()=>(" + String(attrValue) + ')(this.refs["' + refId + '"])');
1078
1080
  attr = " data-ref=" + toAttrStringLit(rc.fc.id + ":" + refId);
1079
1081
  }
@@ -1244,9 +1246,9 @@ function createThisProxy(rc, scopeId) {
1244
1246
  return (effect) => {
1245
1247
  effects.push(String(effect));
1246
1248
  };
1247
- case Symbol.for("effects"):
1249
+ case /* @__PURE__ */ Symbol.for("effects"):
1248
1250
  return effects;
1249
- case Symbol.for("mark"):
1251
+ case /* @__PURE__ */ Symbol.for("mark"):
1250
1252
  return mark;
1251
1253
  case "url":
1252
1254
  if (scopeId === 0) {
@@ -1345,7 +1347,7 @@ async function createSession(request, options) {
1345
1347
  return session;
1346
1348
  }
1347
1349
  function markSignals(rc, signals) {
1348
- signals[Symbol.for("mark")](rc);
1350
+ signals[/* @__PURE__ */ Symbol.for("mark")](rc);
1349
1351
  }
1350
1352
  function traverseProps(obj, callback, path = []) {
1351
1353
  const isArray = Array.isArray(obj);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mono-jsx",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "description": "`<html>` as a `Response`.",
5
5
  "type": "module",
6
6
  "module": "./index.mjs",
@@ -1,3 +1,8 @@
1
1
  /// <reference types="../jsx.d.ts" />
2
2
 
3
- export const Store: <T extends Record<string, unknown>>(initValue: T) => FC & T;
3
+ export interface IAtom<T> {
4
+ value: T;
5
+ }
6
+
7
+ export const atom: <T>(initValue: T) => IAtom<T>;
8
+ export const store: <T extends Record<string, unknown>>(initValue: T) => T;
@@ -1,5 +1,4 @@
1
1
  import type { ComponentType, VNode } from "../jsx.d.ts";
2
- import type * as Mono from "./mono.d.ts";
3
2
 
4
3
  export const html: JSX.Raw;
5
4
  export const JSX: typeof globalThis.JSX;
@@ -10,8 +9,13 @@ export const jsx: (tag: string | ComponentType, props: Record<string, unknown>,
10
9
  export { html as css, html as js, jsx as jsxDEV, jsx as jsxs };
11
10
 
12
11
  declare global {
13
- namespace JSX {
14
- interface BuiltinElements extends Mono.Elements {}
12
+ interface FCExtension<FC> {
13
+ /**
14
+ * Creates a new signals object.
15
+ *
16
+ * **⚠ This is a client-side only API.**
17
+ */
18
+ extend<T extends Record<string, unknown>>(initValue: T): FC & T;
15
19
  }
16
20
 
17
21
  interface HTMLElement {
package/types/jsx.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import type { HTML } from "./html.d.ts";
2
2
 
3
- export type ChildType = MaybeArray<JSX.Element | string | number | bigint | boolean | null | undefined>;
3
+ export type ChildPrimitiveType = JSX.Element | string | number | bigint | boolean | null | undefined;
4
+ export type ChildType = MaybeArray<ChildPrimitiveType | MaybeGetter<ChildPrimitiveType>>;
4
5
  export type MaybeArray<T> = T | T[];
6
+ export type MaybeGetter<T> = { value: T };
5
7
  export type MaybePromiseOrGenerator<T> = T | Promise<T> | Generator<T> | AsyncGenerator<T>;
6
8
 
7
9
  export interface BaseAttributes {
@@ -57,6 +59,57 @@ export interface ComponentType<P = {}> {
57
59
  rendering?: string;
58
60
  }
59
61
 
62
+ export interface MonoBuiltinElements {
63
+ /**
64
+ * A built-in element of mono-jsx that toggles the visibility of its children.
65
+ * @mono-jsx
66
+ */
67
+ show: BaseAttributes & {
68
+ /**
69
+ * Show the children if the value is truthy.
70
+ */
71
+ when?: any;
72
+
73
+ /**
74
+ * Enables view transition for the children.
75
+ */
76
+ viewTransition?: string | boolean;
77
+ };
78
+
79
+ /**
80
+ * A built-in element of mono-jsx that toggles the visibility of its children.
81
+ * @mono-jsx
82
+ */
83
+ hidden: BaseAttributes & {
84
+ /**
85
+ * Hide the children if the value is truthy.
86
+ */
87
+ when?: any;
88
+
89
+ /**
90
+ * Enables view transition for the children.
91
+ */
92
+ viewTransition?: string | boolean;
93
+ };
94
+
95
+ /**
96
+ * A a built-in element of mono-jsx that chooses one of its children based on the `slot` attribute to display.
97
+ * It is similar to a switch statement in programming languages.
98
+ * @mono-jsx
99
+ */
100
+ switch: BaseAttributes & {
101
+ /**
102
+ * Which child to display.
103
+ */
104
+ value?: string | number | boolean | null;
105
+
106
+ /**
107
+ * Enables view transition for the children.
108
+ */
109
+ viewTransition?: string | boolean;
110
+ };
111
+ }
112
+
60
113
  declare global {
61
114
  namespace JSX {
62
115
  type ElementType<P = any> =
@@ -71,7 +124,7 @@ declare global {
71
124
  interface CustomElements {}
72
125
  interface Element extends VNode, Response {}
73
126
  interface IntrinsicAttributes extends BaseAttributes, AsyncComponentAttributes {}
74
- interface IntrinsicElements extends HTML.Elements, HTML.SVGElements, HTML.CustomElements, JSX.BuiltinElements {}
127
+ interface IntrinsicElements extends HTML.Elements, HTML.SVGElements, HTML.CustomElements, JSX.BuiltinElements, MonoBuiltinElements {}
75
128
  }
76
129
 
77
130
  interface FCExtension<FC = {}> {}
package/types/mono.d.ts CHANGED
@@ -3,55 +3,6 @@ import type { AsyncComponentAttributes, BaseAttributes, ComponentType } from "./
3
3
  export type WithParams<T> = T & { params?: Record<string, string> };
4
4
 
5
5
  export interface Elements {
6
- /**
7
- * A built-in element of mono-jsx that toggles the visibility of its children.
8
- * @mono-jsx
9
- */
10
- show: BaseAttributes & {
11
- /**
12
- * Show the children if the value is truthy.
13
- */
14
- when?: any;
15
-
16
- /**
17
- * Enables view transition for the children.
18
- */
19
- viewTransition?: string | boolean;
20
- };
21
-
22
- /**
23
- * A built-in element of mono-jsx that toggles the visibility of its children.
24
- * @mono-jsx
25
- */
26
- hidden: BaseAttributes & {
27
- /**
28
- * Hide the children if the value is truthy.
29
- */
30
- when?: any;
31
-
32
- /**
33
- * Enables view transition for the children.
34
- */
35
- viewTransition?: string | boolean;
36
- };
37
-
38
- /**
39
- * A a built-in element of mono-jsx that chooses one of its children based on the `slot` attribute to display.
40
- * It is similar to a switch statement in programming languages.
41
- * @mono-jsx
42
- */
43
- switch: BaseAttributes & {
44
- /**
45
- * Which child to display.
46
- */
47
- value?: string | number | boolean | null;
48
-
49
- /**
50
- * Enables view transition for the children.
51
- */
52
- viewTransition?: string | boolean;
53
- };
54
-
55
6
  /**
56
7
  * A built-in element of mono-jsx that is used to load components lazily,
57
8
  * which can improve performance by reducing the initial load time of the application.
@@ -238,7 +189,7 @@ export interface Session {
238
189
  }
239
190
 
240
191
  declare global {
241
- interface FCExtension {
192
+ interface FCExtension<FC> {
242
193
  /**
243
194
  * The global signals shared across the application.
244
195
  */
@@ -1,65 +0,0 @@
1
- import type { BaseAttributes } from "../jsx.d.ts";
2
-
3
- export interface Elements {
4
- /**
5
- * A built-in element of mono-jsx that toggles the visibility of its children.
6
- * @mono-jsx
7
- */
8
- show: BaseAttributes & {
9
- /**
10
- * Show the children if the value is truthy.
11
- */
12
- when?: any;
13
-
14
- /**
15
- * Enables view transition for the children.
16
- */
17
- viewTransition?: string | boolean;
18
- };
19
-
20
- hidden: BaseAttributes & {
21
- /**
22
- * Hide the children if the value is truthy.
23
- */
24
- when?: any;
25
-
26
- /**
27
- * Enables view transition for the children.
28
- */
29
- viewTransition?: string | boolean;
30
- };
31
-
32
- /**
33
- * A a built-in element of mono-jsx that chooses one of its children based on the `slot` attribute to display.
34
- * It is similar to a switch statement in programming languages.
35
- * @mono-jsx
36
- */
37
- switch: BaseAttributes & {
38
- /**
39
- * Which child to display.
40
- */
41
- value?: string | number | boolean | null;
42
-
43
- /**
44
- * Enables view transition for the children.
45
- */
46
- viewTransition?: string | boolean;
47
- };
48
- }
49
-
50
- declare global {
51
- interface FCExtension<FC> {
52
- /**
53
- * Creates a new signals object.
54
- *
55
- * **⚠ This is a client-side only API.**
56
- */
57
- extend<T extends Record<string, unknown>>(initValue: T): FC & T;
58
- }
59
-
60
- /**
61
- * Creates a new signals object.
62
- * @mono-jsx
63
- */
64
- var Store: <T extends Record<string, unknown>>(initValue: T) => FC & T;
65
- }