regor 1.7.0 → 1.7.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
@@ -24,7 +24,7 @@ Its template syntax is familiar to Vue users (`r-if`, `r-model`, `r-for`, `r-bin
24
24
  />
25
25
  ```
26
26
 
27
- - **Flexible Reactivity:** Combine `ref`, `sref`, `batch`, `pause`, `resume`, and `entangle` for explicit state orchestration.
27
+ - **Flexible Reactivity:** Combine `ref`, `cref`, `sref`, `batch`, `pause`, `resume`, and `entangle` for explicit state orchestration.
28
28
  - **Static-First + Islands:** Bind to existing DOM without removing server-rendered HTML, ideal for progressive enhancement.
29
29
  - **Reentrance:** Mount multiple times in already-mounted regions with same or different app contexts.
30
30
  - **Compatibility:** Rendered pages are designed for seamless integration with other libraries manipulating the DOM.
@@ -340,7 +340,7 @@ Regor is openly inspired by Vue’s concepts (even adopting a similar directive
340
340
  ### Reactivity control model
341
341
 
342
342
  - **Vue:** Uses ES6 Proxies for a highly automated, "magical" reactivity system. You update an object, and Vue figures out what to re-render. However, this magic can sometimes abstract away performance bottlenecks, leading to over-rendering if you aren't careful with deep reactivity.
343
- - **Regor:** Provides fine-tuned, manual control. It offers `ref` (deep reactivity) and `sref` (simple/shallow reactivity without nested observation). Furthermore, Regor provides advanced control APIs like `pause()` and `resume()` to stop a ref's auto-triggers, `entangle()` to sync two refs effortlessly, and `batch()` for precise state grouping.
343
+ - **Regor:** Provides fine-tuned, manual control. It offers `ref` (deep in-place reactivity), `cref` (copy-first deep reactivity), and `sref` (simple/shallow reactivity without nested observation). Furthermore, Regor provides advanced control APIs like `pause()` and `resume()` to stop a ref's auto-triggers, `entangle()` to sync two refs effortlessly, and `batch()` for precise state grouping.
344
344
  - **Verdict:** Vue's reactivity is easier for beginners.. Regor’s reactivity is more flexible and transparent, giving engineers exact tools to orchestrate update semantics and prevent unwanted DOM paints.
345
345
 
346
346
  ### TypeScript ergonomics
@@ -428,6 +428,7 @@ These directives empower you to create dynamic and interactive user interfaces,
428
428
  **Reactivity Functions**
429
429
 
430
430
  - **`ref`** Creates a deep ref object recursively, modifying the source object in place.
431
+ - **`cref`** Creates a deep ref object recursively from a flattened copy of the source object.
431
432
  - **`sref`** Creates a simple ref object from a given value, without nested ref creation.
432
433
  - **`isDeepRef`** Returns true if a given ref is created with `ref()` function.
433
434
  - **`isRef`** Returns true for any ref, false for non-refs.
package/dist/regor.d.ts CHANGED
@@ -333,6 +333,7 @@ export type BivariantAnyRefCall = {
333
333
  bivarianceHack(newValue?: unknown, eventSource?: unknown): unknown;
334
334
  }["bivarianceHack"];
335
335
  export type AnyRef = BivariantAnyRefCall;
336
+ export type CompProp<TValueType> = Ref<TValueType> | SRef<TValueType>;
336
337
  export type RefOrValue<TValueType> = Ref<TValueType> | SRef<TValueType> | TValueType;
337
338
  export type RefSetterValue<TValueType> = RefContent<TValueType> | Ref<RefParam<TValueType>> | SRef<RefContent<TValueType>>;
338
339
  export type RefValueSetterValue<TValueType> = TValueType extends readonly unknown[] ? Ref<RefParam<TValueType>> | SRef<RefContent<TValueType>> : RefSetterValue<TValueType>;
@@ -777,11 +778,21 @@ export declare const observerCount: <TValueType extends AnyRef>(source: TValueTy
777
778
  export declare const batch: (updater: () => void) => void;
778
779
  export declare const startBatch: () => void;
779
780
  export declare const endBatch: () => void;
781
+ /**
782
+ * Creates a deep ref from a flattened copy of the given value.
783
+ *
784
+ * Unlike `ref`, this does not mutate the original object graph during initial
785
+ * conversion. cref is slower than ref. Use it when you need to preserve original object.
786
+ */
787
+ export declare function cref<TValueType>(value?: TValueType | RefContent<TValueType> | (TValueType extends Ref<infer V1> ? Ref<RefParam<V1>> : never) | (TValueType extends SRef<infer V2> ? SRef<UnwrapRef<V2>> : never) | RefParam<TValueType> | (TValueType extends Array<infer V1> ? V1[] : never) | null): IsNull<TValueType> extends true ? Ref<unknown> : Ref<RefParam<TValueType>>;
780
788
  export declare const entangle: (r1: AnyRef, r2: AnyRef) => StopObserving;
781
789
  export declare const isDeepRef: (value: unknown) => value is AnyRef;
782
790
  export declare const isRef: (value: unknown) => value is AnyRef;
783
791
  export declare const pause: <TValueType extends AnyRef>(source: TValueType) => void;
784
792
  /**
793
+ * The ref function mutates given value in place. Use it with caution.
794
+ * If you need to create ref without mutating use cref (which is slower).
795
+ *
785
796
  * Converts the given value and its nested properties into ref objects recursively and returns the ref.
786
797
  * The returned object's type reflects its nested properties as well.
787
798
  *
@@ -839,3 +850,16 @@ export declare function ref<TValueType>(
839
850
  object,
840
851
  ): IsNull<TValueType> extends true ? Ref<unknown> : Ref<RefParam<TValueType>>
841
852
  export declare function ref(value: string, eventSource?: unknown): Ref<string>
853
+
854
+ export declare function cref(value: string): Ref<string>
855
+ export declare function cref(value: number): Ref<number>
856
+ export declare function cref(value: boolean): Ref<boolean>
857
+ export declare function cref(value: bigint): Ref<bigint>
858
+ export declare function cref(value: symbol): Ref<symbol>
859
+ export declare function cref<TValueType>(
860
+ value: (TValueType extends RawTypes | readonly unknown[]
861
+ ? never
862
+ : RefInit<TValueType>) &
863
+ object,
864
+ ): IsNull<TValueType> extends true ? Ref<unknown> : Ref<RefParam<TValueType>>
865
+ export declare function cref(value: string, eventSource?: unknown): Ref<string>
@@ -69,6 +69,7 @@ __export(index_exports, {
69
69
  computeRef: () => computeRef,
70
70
  computed: () => computed,
71
71
  createApp: () => createApp,
72
+ cref: () => cref,
72
73
  defineComponent: () => defineComponent,
73
74
  drainUnbind: () => drainUnbind,
74
75
  endBatch: () => endBatch,
@@ -1230,6 +1231,132 @@ var isScope = (value) => {
1230
1231
  return scopeSymbol2 in value;
1231
1232
  };
1232
1233
 
1234
+ // src/reactivity/unref.ts
1235
+ var unref = (value) => {
1236
+ const anyValue = value;
1237
+ return anyValue != null && anyValue[srefSymbol] > 0 ? anyValue() : anyValue;
1238
+ };
1239
+
1240
+ // src/directives/attr.ts
1241
+ var xlinkNS = "http://www.w3.org/1999/xlink";
1242
+ var booleanAttributes = {
1243
+ itemscope: 2,
1244
+ allowfullscreen: 2,
1245
+ formnovalidate: 2,
1246
+ ismap: 2,
1247
+ nomodule: 2,
1248
+ novalidate: 2,
1249
+ readonly: 2,
1250
+ async: 1,
1251
+ autofocus: 1,
1252
+ autoplay: 1,
1253
+ controls: 1,
1254
+ default: 1,
1255
+ defer: 1,
1256
+ disabled: 1,
1257
+ hidden: 1,
1258
+ inert: 1,
1259
+ loop: 1,
1260
+ open: 1,
1261
+ required: 1,
1262
+ reversed: 1,
1263
+ scoped: 1,
1264
+ seamless: 1,
1265
+ checked: 1,
1266
+ muted: 1,
1267
+ multiple: 1,
1268
+ selected: 1
1269
+ };
1270
+ var updateAttr = (el, values, previousValues, option, previousOption, flags) => {
1271
+ var _a;
1272
+ if (option) {
1273
+ option = unref(option);
1274
+ if (flags && flags.includes("camel")) option = camelize(option);
1275
+ patchAttr(
1276
+ el,
1277
+ option,
1278
+ unref(values[0]),
1279
+ unref(previousOption)
1280
+ );
1281
+ return;
1282
+ }
1283
+ const len = values.length;
1284
+ for (let i = 0; i < len; ++i) {
1285
+ const next = values[i];
1286
+ if (isArray(next)) {
1287
+ const previousKey = unref((_a = previousValues == null ? void 0 : previousValues[i]) == null ? void 0 : _a[0]);
1288
+ const key = unref(next[0]);
1289
+ const value = unref(next[1]);
1290
+ patchAttr(el, key, value, previousKey);
1291
+ } else if (isObject(next)) {
1292
+ for (const item of Object.entries(next)) {
1293
+ const key = item[0];
1294
+ const value = unref(item[1]);
1295
+ const p = unref(previousValues == null ? void 0 : previousValues[i]);
1296
+ const previousKey = p && key in p ? key : void 0;
1297
+ patchAttr(el, key, value, previousKey);
1298
+ }
1299
+ } else {
1300
+ const previousKey = unref(previousValues == null ? void 0 : previousValues[i]);
1301
+ const key = unref(values[i++]);
1302
+ const value = unref(values[i]);
1303
+ patchAttr(el, key, value, previousKey);
1304
+ }
1305
+ }
1306
+ };
1307
+ var attrDirective = {
1308
+ mount: () => ({
1309
+ update: ({ el, values, previousValues, option, previousOption, flags }) => {
1310
+ updateAttr(
1311
+ el,
1312
+ values,
1313
+ previousValues,
1314
+ option,
1315
+ previousOption,
1316
+ flags
1317
+ );
1318
+ }
1319
+ })
1320
+ };
1321
+ var patchAttr = (el, key, value, previousKey) => {
1322
+ if (previousKey && previousKey !== key) {
1323
+ el.removeAttribute(previousKey);
1324
+ }
1325
+ if (isNullOrUndefined(key)) {
1326
+ warning(3 /* KeyIsEmpty */, "r-bind", el);
1327
+ return;
1328
+ }
1329
+ if (!isString(key)) {
1330
+ warning(
1331
+ 6 /* ErrorLog */,
1332
+ `Attribute key is not string at ${el.outerHTML}`,
1333
+ key
1334
+ );
1335
+ return;
1336
+ }
1337
+ if (key.startsWith("xlink:")) {
1338
+ if (isNullOrUndefined(value)) {
1339
+ el.removeAttributeNS(xlinkNS, key.slice(6, key.length));
1340
+ } else {
1341
+ el.setAttributeNS(xlinkNS, key, value);
1342
+ }
1343
+ return;
1344
+ }
1345
+ if (isNullOrUndefined(value)) {
1346
+ el.removeAttribute(key);
1347
+ return;
1348
+ }
1349
+ if (key in booleanAttributes) {
1350
+ if (toBoolean(value)) {
1351
+ el.setAttribute(key, "");
1352
+ } else {
1353
+ el.removeAttribute(key);
1354
+ }
1355
+ return;
1356
+ }
1357
+ el.setAttribute(key, value);
1358
+ };
1359
+
1233
1360
  // src/directives/context.ts
1234
1361
  var contextDirective = {
1235
1362
  collectRefObj: true,
@@ -1968,10 +2095,11 @@ var ComponentBinder = class {
1968
2095
  } else if (attrName === ":style" || attrName === bindStyleName) {
1969
2096
  mergeBinding(":style", bindStyleName, value);
1970
2097
  } else {
1971
- inheritor.setAttribute(
1972
- normalizeAttributeName(attrName, binder.__config),
1973
- value
2098
+ const normalizedName = normalizeAttributeName(
2099
+ attrName,
2100
+ binder.__config
1974
2101
  );
2102
+ patchAttr(inheritor, normalizedName, value);
1975
2103
  }
1976
2104
  };
1977
2105
  for (const { name, value } of inheritedPropAttrs) {
@@ -2313,12 +2441,6 @@ var DynamicBinder = class {
2313
2441
  }
2314
2442
  };
2315
2443
 
2316
- // src/reactivity/unref.ts
2317
- var unref = (value) => {
2318
- const anyValue = value;
2319
- return anyValue != null && anyValue[srefSymbol] > 0 ? anyValue() : anyValue;
2320
- };
2321
-
2322
2444
  // src/directives/html.ts
2323
2445
  var updateHtml = (el, values) => {
2324
2446
  const [value, replacer] = values;
@@ -3268,116 +3390,6 @@ var Binder = class {
3268
3390
  }
3269
3391
  };
3270
3392
 
3271
- // src/directives/attr.ts
3272
- var xlinkNS = "http://www.w3.org/1999/xlink";
3273
- var booleanAttributes = {
3274
- itemscope: 2,
3275
- allowfullscreen: 2,
3276
- formnovalidate: 2,
3277
- ismap: 2,
3278
- nomodule: 2,
3279
- novalidate: 2,
3280
- readonly: 2,
3281
- async: 1,
3282
- autofocus: 1,
3283
- autoplay: 1,
3284
- controls: 1,
3285
- default: 1,
3286
- defer: 1,
3287
- disabled: 1,
3288
- hidden: 1,
3289
- inert: 1,
3290
- loop: 1,
3291
- open: 1,
3292
- required: 1,
3293
- reversed: 1,
3294
- scoped: 1,
3295
- seamless: 1,
3296
- checked: 1,
3297
- muted: 1,
3298
- multiple: 1,
3299
- selected: 1
3300
- };
3301
- function includeBooleanAttr(value) {
3302
- return !!value || value === "";
3303
- }
3304
- var updateAttr = (el, values, previousValues, option, previousOption, flags) => {
3305
- var _a;
3306
- if (option) {
3307
- if (flags && flags.includes("camel")) option = camelize(option);
3308
- patchAttribute(el, option, values[0], previousOption);
3309
- return;
3310
- }
3311
- const len = values.length;
3312
- for (let i = 0; i < len; ++i) {
3313
- const next = values[i];
3314
- if (isArray(next)) {
3315
- const previousKey = (_a = previousValues == null ? void 0 : previousValues[i]) == null ? void 0 : _a[0];
3316
- const key = next[0];
3317
- const value = next[1];
3318
- patchAttribute(el, key, value, previousKey);
3319
- } else if (isObject(next)) {
3320
- for (const item of Object.entries(next)) {
3321
- const key = item[0];
3322
- const value = item[1];
3323
- const p = previousValues == null ? void 0 : previousValues[i];
3324
- const previousKey = p && key in p ? key : void 0;
3325
- patchAttribute(el, key, value, previousKey);
3326
- }
3327
- } else {
3328
- const previousKey = previousValues == null ? void 0 : previousValues[i];
3329
- const key = values[i++];
3330
- const value = values[i];
3331
- patchAttribute(el, key, value, previousKey);
3332
- }
3333
- }
3334
- };
3335
- var attrDirective = {
3336
- mount: () => ({
3337
- update: ({ el, values, previousValues, option, previousOption, flags }) => {
3338
- updateAttr(
3339
- el,
3340
- values,
3341
- previousValues,
3342
- option,
3343
- previousOption,
3344
- flags
3345
- );
3346
- }
3347
- })
3348
- };
3349
- var patchAttribute = (el, key, value, previousKey) => {
3350
- if (previousKey && previousKey !== key) {
3351
- el.removeAttribute(previousKey);
3352
- }
3353
- if (isNullOrUndefined(key)) {
3354
- warning(3 /* KeyIsEmpty */, "r-bind", el);
3355
- return;
3356
- }
3357
- if (!isString(key)) {
3358
- warning(
3359
- 6 /* ErrorLog */,
3360
- `Attribute key is not string at ${el.outerHTML}`,
3361
- key
3362
- );
3363
- return;
3364
- }
3365
- if (key.startsWith("xlink:")) {
3366
- if (isNullOrUndefined(value)) {
3367
- el.removeAttributeNS(xlinkNS, key.slice(6, key.length));
3368
- } else {
3369
- el.setAttributeNS(xlinkNS, key, value);
3370
- }
3371
- return;
3372
- }
3373
- const isBoolean2 = key in booleanAttributes;
3374
- if (isNullOrUndefined(value) || isBoolean2 && !includeBooleanAttr(value)) {
3375
- el.removeAttribute(key);
3376
- } else {
3377
- el.setAttribute(key, isBoolean2 ? "" : value);
3378
- }
3379
- };
3380
-
3381
3393
  // src/directives/class.ts
3382
3394
  var updateClass = (el, values, previousValues) => {
3383
3395
  const len = values.length;
@@ -4024,7 +4036,7 @@ var propDirective = {
4024
4036
  }
4025
4037
  })
4026
4038
  };
4027
- function includeBooleanAttr2(value) {
4039
+ function includeBooleanAttr(value) {
4028
4040
  return !!value || value === "";
4029
4041
  }
4030
4042
  var patchProp = (el, key, value) => {
@@ -4056,7 +4068,7 @@ var patchProp = (el, key, value) => {
4056
4068
  if (value === "" || value == null) {
4057
4069
  const type = typeof el[key];
4058
4070
  if (type === "boolean") {
4059
- value = includeBooleanAttr2(value);
4071
+ value = includeBooleanAttr(value);
4060
4072
  } else if (value == null && type === "string") {
4061
4073
  value = "";
4062
4074
  needRemove = true;
@@ -4222,6 +4234,8 @@ var flatten = (reference) => {
4222
4234
  var flattenContent = (value, weakMap = /* @__PURE__ */ new WeakMap()) => {
4223
4235
  if (!value) return value;
4224
4236
  if (!isObject(value)) return value;
4237
+ if (value instanceof Node || value instanceof Date || value instanceof RegExp || value instanceof Promise || value instanceof Error)
4238
+ return value;
4225
4239
  if (isArray(value)) {
4226
4240
  return value.map(flatten);
4227
4241
  }
@@ -4310,6 +4324,11 @@ function ref(value) {
4310
4324
  return result;
4311
4325
  }
4312
4326
 
4327
+ // src/reactivity/cref.ts
4328
+ function cref(value) {
4329
+ return ref(flatten(value));
4330
+ }
4331
+
4313
4332
  // src/app/RegorConfig.ts
4314
4333
  var _RegorConfig = class _RegorConfig {
4315
4334
  constructor(globalContext) {
@@ -4370,6 +4389,7 @@ var _RegorConfig = class _RegorConfig {
4370
4389
  obj[key] = global[key];
4371
4390
  }
4372
4391
  obj.ref = ref;
4392
+ obj.cref = cref;
4373
4393
  obj.sref = sref;
4374
4394
  obj.flatten = flatten;
4375
4395
  return obj;