@panneau/core 4.1.1 → 5.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -0
- package/dist/definition/abilities.d.ts +21 -0
- package/dist/definition/abilities.d.ts.map +1 -0
- package/dist/definition/abilities.js +47 -0
- package/dist/definition/abilities.js.map +1 -0
- package/dist/definition/form.d.ts +31 -0
- package/dist/definition/form.d.ts.map +1 -0
- package/dist/definition/form.js +54 -0
- package/dist/definition/form.js.map +1 -0
- package/dist/definition/list.d.ts +44 -0
- package/dist/definition/list.d.ts.map +1 -0
- package/dist/definition/list.js +70 -0
- package/dist/definition/list.js.map +1 -0
- package/dist/definition/resource.d.ts +21 -0
- package/dist/definition/resource.d.ts.map +1 -0
- package/dist/definition/resource.js +24 -0
- package/dist/definition/resource.js.map +1 -0
- package/dist/form/form.d.ts +148 -0
- package/dist/form/form.d.ts.map +1 -0
- package/dist/form/form.js +239 -0
- package/dist/form/form.js.map +1 -0
- package/dist/form/messages.d.ts +7 -0
- package/dist/form/messages.d.ts.map +1 -0
- package/dist/form/messages.js +25 -0
- package/dist/form/messages.js.map +1 -0
- package/dist/form/problem.d.ts +16 -0
- package/dist/form/problem.d.ts.map +1 -0
- package/dist/form/problem.js +34 -0
- package/dist/form/problem.js.map +1 -0
- package/dist/form/selectors.d.ts +16 -0
- package/dist/form/selectors.d.ts.map +1 -0
- package/dist/form/selectors.js +27 -0
- package/dist/form/selectors.js.map +1 -0
- package/dist/form/store.d.ts +19 -0
- package/dist/form/store.d.ts.map +1 -0
- package/dist/form/store.js +29 -0
- package/dist/form/store.js.map +1 -0
- package/dist/index.d.ts +17 -692
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -536
- package/dist/list/list.d.ts +68 -0
- package/dist/list/list.d.ts.map +1 -0
- package/dist/list/list.js +191 -0
- package/dist/list/list.js.map +1 -0
- package/dist/list/router.d.ts +26 -0
- package/dist/list/router.d.ts.map +1 -0
- package/dist/list/router.js +54 -0
- package/dist/list/router.js.map +1 -0
- package/dist/plugins.d.ts +73 -0
- package/dist/plugins.d.ts.map +1 -0
- package/dist/plugins.js +54 -0
- package/dist/plugins.js.map +1 -0
- package/dist/react/provider.d.ts +38 -0
- package/dist/react/provider.d.ts.map +1 -0
- package/dist/react/provider.js +63 -0
- package/dist/react/provider.js.map +1 -0
- package/dist/react/useForm.d.ts +26 -0
- package/dist/react/useForm.d.ts.map +1 -0
- package/dist/react/useForm.js +115 -0
- package/dist/react/useForm.js.map +1 -0
- package/dist/react/useList.d.ts +11 -0
- package/dist/react/useList.d.ts.map +1 -0
- package/dist/react/useList.js +47 -0
- package/dist/react/useList.js.map +1 -0
- package/dist/values.d.ts +12 -0
- package/dist/values.d.ts.map +1 -0
- package/dist/values.js +44 -0
- package/dist/values.js.map +1 -0
- package/package.json +19 -81
- package/dist/contexts.d.ts +0 -667
- package/dist/contexts.js +0 -1772
- package/dist/hooks.d.ts +0 -512
- package/dist/hooks.js +0 -2146
- package/dist/utils.d.ts +0 -457
- package/dist/utils.js +0 -557
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { selectErrors, selectValue } from "../form/selectors.js";
|
|
2
|
+
import { createForm } from "../form/form.js";
|
|
3
|
+
import { c } from "react/compiler-runtime";
|
|
4
|
+
import { useLayoutEffect, useState, useSyncExternalStore } from "react";
|
|
5
|
+
//#region src/react/useForm.ts
|
|
6
|
+
/**
|
|
7
|
+
* Creates a form for the life of the component. `fields`, `locales`, `formatError` and `onSubmit`
|
|
8
|
+
* follow the latest render; initial values and the version don't: call `form.reset()`, or give
|
|
9
|
+
* the component a new `key`, to start from another item.
|
|
10
|
+
*
|
|
11
|
+
* Read the returned state with the selectors (`selectErrors(state, path)`,
|
|
12
|
+
* `selectVisible(state, field)`…), not with the form's reading methods, which go stale with the
|
|
13
|
+
* React Compiler (see {@link Form}).
|
|
14
|
+
*/
|
|
15
|
+
function useForm(options) {
|
|
16
|
+
const $ = c(11);
|
|
17
|
+
let t0;
|
|
18
|
+
if ($[0] !== options) {
|
|
19
|
+
t0 = () => createForm(options);
|
|
20
|
+
$[0] = options;
|
|
21
|
+
$[1] = t0;
|
|
22
|
+
} else t0 = $[1];
|
|
23
|
+
const [form] = useState(t0);
|
|
24
|
+
const { fields, locales, formatError, onSubmit } = options;
|
|
25
|
+
let t1;
|
|
26
|
+
if ($[2] !== fields || $[3] !== form || $[4] !== formatError || $[5] !== locales || $[6] !== onSubmit) {
|
|
27
|
+
t1 = () => {
|
|
28
|
+
form.setOptions({
|
|
29
|
+
fields,
|
|
30
|
+
locales,
|
|
31
|
+
formatError,
|
|
32
|
+
onSubmit
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
$[2] = fields;
|
|
36
|
+
$[3] = form;
|
|
37
|
+
$[4] = formatError;
|
|
38
|
+
$[5] = locales;
|
|
39
|
+
$[6] = onSubmit;
|
|
40
|
+
$[7] = t1;
|
|
41
|
+
} else t1 = $[7];
|
|
42
|
+
useLayoutEffect(t1);
|
|
43
|
+
const state = useSyncExternalStore(form.subscribe, form.getState, form.getState);
|
|
44
|
+
let t2;
|
|
45
|
+
if ($[8] !== form || $[9] !== state) {
|
|
46
|
+
t2 = {
|
|
47
|
+
...state,
|
|
48
|
+
form
|
|
49
|
+
};
|
|
50
|
+
$[8] = form;
|
|
51
|
+
$[9] = state;
|
|
52
|
+
$[10] = t2;
|
|
53
|
+
} else t2 = $[10];
|
|
54
|
+
return t2;
|
|
55
|
+
}
|
|
56
|
+
/** Props for a controlled field at a dot path of a form. */
|
|
57
|
+
function useFormField(form, path) {
|
|
58
|
+
const $ = c(19);
|
|
59
|
+
const state = useSyncExternalStore(form.subscribe, form.getState, form.getState);
|
|
60
|
+
let t0;
|
|
61
|
+
if ($[0] !== path || $[1] !== state) {
|
|
62
|
+
t0 = selectValue(state, path);
|
|
63
|
+
$[0] = path;
|
|
64
|
+
$[1] = state;
|
|
65
|
+
$[2] = t0;
|
|
66
|
+
} else t0 = $[2];
|
|
67
|
+
let t1;
|
|
68
|
+
let t2;
|
|
69
|
+
if ($[3] !== form || $[4] !== path) {
|
|
70
|
+
t1 = (value) => form.setValue(path, value);
|
|
71
|
+
t2 = () => form.blur(path);
|
|
72
|
+
$[3] = form;
|
|
73
|
+
$[4] = path;
|
|
74
|
+
$[5] = t1;
|
|
75
|
+
$[6] = t2;
|
|
76
|
+
} else {
|
|
77
|
+
t1 = $[5];
|
|
78
|
+
t2 = $[6];
|
|
79
|
+
}
|
|
80
|
+
let t3;
|
|
81
|
+
if ($[7] !== path || $[8] !== state) {
|
|
82
|
+
t3 = selectErrors(state, path, { nested: true });
|
|
83
|
+
$[7] = path;
|
|
84
|
+
$[8] = state;
|
|
85
|
+
$[9] = t3;
|
|
86
|
+
} else t3 = $[9];
|
|
87
|
+
let t4;
|
|
88
|
+
if ($[10] !== path || $[11] !== state.touched) {
|
|
89
|
+
t4 = state.touched.has(path);
|
|
90
|
+
$[10] = path;
|
|
91
|
+
$[11] = state.touched;
|
|
92
|
+
$[12] = t4;
|
|
93
|
+
} else t4 = $[12];
|
|
94
|
+
let t5;
|
|
95
|
+
if ($[13] !== t0 || $[14] !== t1 || $[15] !== t2 || $[16] !== t3 || $[17] !== t4) {
|
|
96
|
+
t5 = {
|
|
97
|
+
value: t0,
|
|
98
|
+
onChange: t1,
|
|
99
|
+
onBlur: t2,
|
|
100
|
+
errors: t3,
|
|
101
|
+
touched: t4
|
|
102
|
+
};
|
|
103
|
+
$[13] = t0;
|
|
104
|
+
$[14] = t1;
|
|
105
|
+
$[15] = t2;
|
|
106
|
+
$[16] = t3;
|
|
107
|
+
$[17] = t4;
|
|
108
|
+
$[18] = t5;
|
|
109
|
+
} else t5 = $[18];
|
|
110
|
+
return t5;
|
|
111
|
+
}
|
|
112
|
+
//#endregion
|
|
113
|
+
export { useForm, useFormField };
|
|
114
|
+
|
|
115
|
+
//# sourceMappingURL=useForm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useForm.js","names":["_c"],"sources":["../../src/react/useForm.ts"],"sourcesContent":["import { useLayoutEffect, useState, useSyncExternalStore } from 'react';\n\nimport { type Form, type FormOptions, type FormState, createForm } from '../form/form';\nimport { selectErrors, selectValue } from '../form/selectors';\n\nexport interface UseFormResult extends FormState {\n /** The form, to change values, submit, reset or resolve a conflict. */\n form: Form;\n}\n\n/**\n * Creates a form for the life of the component. `fields`, `locales`, `formatError` and `onSubmit`\n * follow the latest render; initial values and the version don't: call `form.reset()`, or give\n * the component a new `key`, to start from another item.\n *\n * Read the returned state with the selectors (`selectErrors(state, path)`,\n * `selectVisible(state, field)`…), not with the form's reading methods, which go stale with the\n * React Compiler (see {@link Form}).\n */\nexport function useForm(options: FormOptions): UseFormResult {\n const [form] = useState(() => createForm(options));\n const { fields, locales, formatError, onSubmit } = options;\n useLayoutEffect(() => {\n form.setOptions({ fields, locales, formatError, onSubmit });\n });\n const state = useSyncExternalStore(form.subscribe, form.getState, form.getState);\n return { ...state, form };\n}\n\nexport interface UseFormFieldResult {\n value: unknown;\n onChange: (value: unknown) => void;\n onBlur: () => void;\n /** Errors at the path, and at nested paths (`title.fr` for `title`). */\n errors: string[];\n touched: boolean;\n}\n\n/** Props for a controlled field at a dot path of a form. */\nexport function useFormField(form: Form, path: string): UseFormFieldResult {\n const state = useSyncExternalStore(form.subscribe, form.getState, form.getState);\n return {\n value: selectValue(state, path),\n onChange: (value) => form.setValue(path, value),\n onBlur: () => form.blur(path),\n errors: selectErrors(state, path, { nested: true }),\n touched: state.touched.has(path),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;AAmBA,SAAO,QAAA,SAAA;CAAA,MAAA,IAAAA,EAAA,EAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,SAAA;EACqB,WAAM,WAAW,OAAO;EAAC,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAjD,MAAA,CAAA,QAAe,SAAS,EAAyB;CACjD,MAAA,EAAA,QAAA,SAAA,aAAA,aAAmD;CAAQ,IAAA;CAAA,IAAA,EAAA,OAAA,UAAA,EAAA,OAAA,QAAA,EAAA,OAAA,eAAA,EAAA,OAAA,WAAA,EAAA,OAAA,UAAA;EAC3C,WAAA;GACZ,KAAI,WAAY;IAAA;IAAA;IAAA;IAAA;GAAyC,CAAC;EAAC;EAC9D,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAFD,gBAAgB,EAEf;CACD,MAAA,QAAc,qBAAqB,KAAI,WAAY,KAAI,UAAW,KAAI,QAAS;CAAE,IAAA;CAAA,IAAA,EAAA,OAAA,QAAA,EAAA,OAAA,OAAA;EAC1E,KAAA;GAAA,GAAK;GAAK;EAAO;EAAC,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,MAAA;CAAA,OAAA,KAAA,EAAA;CAAA,OAAlB;AAAkB;;AAa7B,SAAO,aAAA,MAAA,MAAA;CAAA,MAAA,IAAAA,EAAA,EAAA;CACH,MAAA,QAAc,qBAAqB,KAAI,WAAY,KAAI,UAAW,KAAI,QAAS;CAAE,IAAA;CAAA,IAAA,EAAA,OAAA,QAAA,EAAA,OAAA,OAAA;EAEtE,KAAA,YAAY,OAAO,IAAI;EAAC,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAA,IAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,QAAA,EAAA,OAAA,MAAA;EACrB,MAAA,UAAW,KAAI,SAAU,MAAM,KAAK;EACtC,WAAM,KAAI,KAAM,IAAI;EAAC,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA;EAAA,KAAA,EAAA;EAAA,KAAA,EAAA;CAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,QAAA,EAAA,OAAA,OAAA;EACrB,KAAA,aAAa,OAAO,MAAM,EAAA,QAAU,KAAK,CAAC;EAAC,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAA,IAAA;CAAA,IAAA,EAAA,QAAA,QAAA,EAAA,QAAA,MAAA,SAAA;EAC1C,KAAA,MAAK,QAAQ,IAAK,IAAI;EAAC,EAAA,MAAA;EAAA,EAAA,MAAA,MAAA;EAAA,EAAA,MAAA;CAAA,OAAA,KAAA,EAAA;CAAA,IAAA;CAAA,IAAA,EAAA,QAAA,MAAA,EAAA,QAAA,MAAA,EAAA,QAAA,MAAA,EAAA,QAAA,MAAA,EAAA,QAAA,IAAA;EAL7B,KAAA;GAAA,OACI;GAAwB,UACrB;GAAqC,QACvC;GAAqB,QACrB;GAA2C,SAC1C;EACb;EAAC,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;CAAA,OAAA,KAAA,EAAA;CAAA,OANM;AAMN"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type List, type ListOptions, type ListState } from '../list/list';
|
|
2
|
+
export interface UseListResult extends ListState {
|
|
3
|
+
/** The list, to change the query and the selection. */
|
|
4
|
+
list: List;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Creates a list for the life of the component. Without a `router` option, the query is kept in
|
|
8
|
+
* the router of the closest `PanneauProvider`, if any. Pass `router: null` to keep it in memory.
|
|
9
|
+
*/
|
|
10
|
+
export declare function useList(options?: ListOptions): UseListResult;
|
|
11
|
+
//# sourceMappingURL=useList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useList.d.ts","sourceRoot":"","sources":["../../src/react/useList.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAc,MAAM,cAAc,CAAC;AAGvF,MAAM,WAAW,aAAc,SAAQ,SAAS;IAC5C,uDAAuD;IACvD,IAAI,EAAE,IAAI,CAAC;CACd;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,WAAgB,GAAG,aAAa,CAUhE"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { createList } from "../list/list.js";
|
|
2
|
+
import { usePanneau } from "./provider.js";
|
|
3
|
+
import { c } from "react/compiler-runtime";
|
|
4
|
+
import { useState, useSyncExternalStore } from "react";
|
|
5
|
+
//#region src/react/useList.ts
|
|
6
|
+
/**
|
|
7
|
+
* Creates a list for the life of the component. Without a `router` option, the query is kept in
|
|
8
|
+
* the router of the closest `PanneauProvider`, if any. Pass `router: null` to keep it in memory.
|
|
9
|
+
*/
|
|
10
|
+
function useList(t0) {
|
|
11
|
+
const $ = c(8);
|
|
12
|
+
let t1;
|
|
13
|
+
if ($[0] !== t0) {
|
|
14
|
+
t1 = t0 === void 0 ? {} : t0;
|
|
15
|
+
$[0] = t0;
|
|
16
|
+
$[1] = t1;
|
|
17
|
+
} else t1 = $[1];
|
|
18
|
+
const options = t1;
|
|
19
|
+
const context = usePanneau();
|
|
20
|
+
let t2;
|
|
21
|
+
if ($[2] !== context || $[3] !== options) {
|
|
22
|
+
t2 = () => createList({
|
|
23
|
+
...options,
|
|
24
|
+
router: options.router === void 0 ? context.router : options.router
|
|
25
|
+
});
|
|
26
|
+
$[2] = context;
|
|
27
|
+
$[3] = options;
|
|
28
|
+
$[4] = t2;
|
|
29
|
+
} else t2 = $[4];
|
|
30
|
+
const [list] = useState(t2);
|
|
31
|
+
const state = useSyncExternalStore(list.subscribe, list.getState, list.getState);
|
|
32
|
+
let t3;
|
|
33
|
+
if ($[5] !== list || $[6] !== state) {
|
|
34
|
+
t3 = {
|
|
35
|
+
...state,
|
|
36
|
+
list
|
|
37
|
+
};
|
|
38
|
+
$[5] = list;
|
|
39
|
+
$[6] = state;
|
|
40
|
+
$[7] = t3;
|
|
41
|
+
} else t3 = $[7];
|
|
42
|
+
return t3;
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { useList };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=useList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useList.js","names":["_c"],"sources":["../../src/react/useList.ts"],"sourcesContent":["import { useState, useSyncExternalStore } from 'react';\n\nimport { type List, type ListOptions, type ListState, createList } from '../list/list';\nimport { usePanneau } from './provider';\n\nexport interface UseListResult extends ListState {\n /** The list, to change the query and the selection. */\n list: List;\n}\n\n/**\n * Creates a list for the life of the component. Without a `router` option, the query is kept in\n * the router of the closest `PanneauProvider`, if any. Pass `router: null` to keep it in memory.\n */\nexport function useList(options: ListOptions = {}): UseListResult {\n const context = usePanneau();\n const [list] = useState(() =>\n createList({\n ...options,\n router: options.router === undefined ? context.router : options.router,\n }),\n );\n const state = useSyncExternalStore(list.subscribe, list.getState, list.getState);\n return { ...state, list };\n}\n"],"mappings":";;;;;;;;;AAcA,SAAO,QAAA,IAAA;CAAA,MAAA,IAAAA,EAAA,CAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,IAAA;EAAiB,KAAA,OAAA,KAAA,IAAA,CAAwB,IAAxB;EAAyB,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAzB,MAAA,UAAA;CACpB,MAAA,UAAgB,WAAW;CAAE,IAAA;CAAA,IAAA,EAAA,OAAA,WAAA,EAAA,OAAA,SAAA;EACL,WACpB,WAAW;GAAA,GACJ;GAAO,QACF,QAAO,WAAY,KAAA,IAAY,QAAO,SAAU,QAAO;EACnE,CAAC;EAAC,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAJN,MAAA,CAAA,QAAe,SAAS,EAKxB;CACA,MAAA,QAAc,qBAAqB,KAAI,WAAY,KAAI,UAAW,KAAI,QAAS;CAAE,IAAA;CAAA,IAAA,EAAA,OAAA,QAAA,EAAA,OAAA,OAAA;EAC1E,KAAA;GAAA,GAAK;GAAK;EAAO;EAAC,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAA,OAAlB;AAAkB"}
|
package/dist/values.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Values of a form or an item, keyed by field name. */
|
|
2
|
+
export type Values = Record<string, unknown>;
|
|
3
|
+
/**
|
|
4
|
+
* Returns a copy of `values` with `value` at a dot path (`title.fr`, `blocks.2.body`). Missing
|
|
5
|
+
* objects and arrays are created: numeric segments create arrays.
|
|
6
|
+
*/
|
|
7
|
+
export declare function setValue<T extends Values>(values: T, path: string, value: unknown): T;
|
|
8
|
+
/** Deep equality of JSON-like values. */
|
|
9
|
+
export declare function isEqual(a: unknown, b: unknown): boolean;
|
|
10
|
+
/** Whether `path` is `parent` or inside it (`title.fr` is inside `title`). */
|
|
11
|
+
export declare function isPathWithin(path: string, parent: string): boolean;
|
|
12
|
+
//# sourceMappingURL=values.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"values.d.ts","sourceRoot":"","sources":["../src/values.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAuB7C;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,CAAC,CAKrF;AAED,yCAAyC;AACzC,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAiBvD;AAED,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAElE"}
|
package/dist/values.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
//#region src/values.ts
|
|
2
|
+
function isIndex(segment) {
|
|
3
|
+
return /^\d+$/.test(segment);
|
|
4
|
+
}
|
|
5
|
+
function setIn(current, segments, value) {
|
|
6
|
+
const [segment, ...rest] = segments;
|
|
7
|
+
if (segment === void 0) return value;
|
|
8
|
+
if (isIndex(segment)) {
|
|
9
|
+
const array = Array.isArray(current) ? [...current] : [];
|
|
10
|
+
array[Number(segment)] = setIn(array[Number(segment)], rest, value);
|
|
11
|
+
return array;
|
|
12
|
+
}
|
|
13
|
+
const record = current !== null && typeof current === "object" && !Array.isArray(current) ? current : {};
|
|
14
|
+
return {
|
|
15
|
+
...record,
|
|
16
|
+
[segment]: setIn(record[segment], rest, value)
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Returns a copy of `values` with `value` at a dot path (`title.fr`, `blocks.2.body`). Missing
|
|
21
|
+
* objects and arrays are created: numeric segments create arrays.
|
|
22
|
+
*/
|
|
23
|
+
function setValue(values, path, value) {
|
|
24
|
+
if (path === "") return value;
|
|
25
|
+
return setIn(values, path.split("."), value);
|
|
26
|
+
}
|
|
27
|
+
/** Deep equality of JSON-like values. */
|
|
28
|
+
function isEqual(a, b) {
|
|
29
|
+
if (Object.is(a, b)) return true;
|
|
30
|
+
if (a === null || b === null || typeof a !== "object" || typeof b !== "object") return false;
|
|
31
|
+
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
|
32
|
+
if (Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((item, index) => isEqual(item, b[index]));
|
|
33
|
+
const left = a;
|
|
34
|
+
const right = b;
|
|
35
|
+
return [.../* @__PURE__ */ new Set([...Object.keys(left), ...Object.keys(right)])].every((key) => isEqual(left[key], right[key]));
|
|
36
|
+
}
|
|
37
|
+
/** Whether `path` is `parent` or inside it (`title.fr` is inside `title`). */
|
|
38
|
+
function isPathWithin(path, parent) {
|
|
39
|
+
return parent === "" || path === parent || path.startsWith(`${parent}.`);
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
export { isEqual, isPathWithin, setValue };
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=values.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"values.js","names":[],"sources":["../src/values.ts"],"sourcesContent":["/** Values of a form or an item, keyed by field name. */\nexport type Values = Record<string, unknown>;\n\nfunction isIndex(segment: string): boolean {\n return /^\\d+$/.test(segment);\n}\n\nfunction setIn(current: unknown, segments: string[], value: unknown): unknown {\n const [segment, ...rest] = segments;\n if (segment === undefined) {\n return value;\n }\n if (isIndex(segment)) {\n const array = Array.isArray(current) ? [...(current as unknown[])] : [];\n array[Number(segment)] = setIn(array[Number(segment)], rest, value);\n return array;\n }\n const record =\n current !== null && typeof current === 'object' && !Array.isArray(current)\n ? (current as Record<string, unknown>)\n : {};\n return { ...record, [segment]: setIn(record[segment], rest, value) };\n}\n\n/**\n * Returns a copy of `values` with `value` at a dot path (`title.fr`, `blocks.2.body`). Missing\n * objects and arrays are created: numeric segments create arrays.\n */\nexport function setValue<T extends Values>(values: T, path: string, value: unknown): T {\n if (path === '') {\n return value as T;\n }\n return setIn(values, path.split('.'), value) as T;\n}\n\n/** Deep equality of JSON-like values. */\nexport function isEqual(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) {\n return true;\n }\n if (a === null || b === null || typeof a !== 'object' || typeof b !== 'object') {\n return false;\n }\n if (Array.isArray(a) !== Array.isArray(b)) {\n return false;\n }\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((item, index) => isEqual(item, b[index]));\n }\n const left = a as Record<string, unknown>;\n const right = b as Record<string, unknown>;\n const keys = new Set([...Object.keys(left), ...Object.keys(right)]);\n return [...keys].every((key) => isEqual(left[key], right[key]));\n}\n\n/** Whether `path` is `parent` or inside it (`title.fr` is inside `title`). */\nexport function isPathWithin(path: string, parent: string): boolean {\n return parent === '' || path === parent || path.startsWith(`${parent}.`);\n}\n"],"mappings":";AAGA,SAAS,QAAQ,SAA0B;CACvC,OAAO,QAAQ,KAAK,OAAO;AAC/B;AAEA,SAAS,MAAM,SAAkB,UAAoB,OAAyB;CAC1E,MAAM,CAAC,SAAS,GAAG,QAAQ;CAC3B,IAAI,YAAY,KAAA,GACZ,OAAO;CAEX,IAAI,QAAQ,OAAO,GAAG;EAClB,MAAM,QAAQ,MAAM,QAAQ,OAAO,IAAI,CAAC,GAAI,OAAqB,IAAI,CAAA;EACrE,MAAM,OAAO,OAAO,KAAK,MAAM,MAAM,OAAO,OAAO,IAAI,MAAM,KAAK;EAClE,OAAO;CACX;CACA,MAAM,SACF,YAAY,QAAQ,OAAO,YAAY,YAAY,CAAC,MAAM,QAAQ,OAAO,IAClE,UACD,CAAC;CACX,OAAO;EAAE,GAAG;GAAS,UAAU,MAAM,OAAO,UAAU,MAAM,KAAK;CAAE;AACvE;;;;;AAMA,SAAgB,SAA2B,QAAW,MAAc,OAAmB;CACnF,IAAI,SAAS,IACT,OAAO;CAEX,OAAO,MAAM,QAAQ,KAAK,MAAM,GAAG,GAAG,KAAK;AAC/C;;AAGA,SAAgB,QAAQ,GAAY,GAAqB;CACrD,IAAI,OAAO,GAAG,GAAG,CAAC,GACd,OAAO;CAEX,IAAI,MAAM,QAAQ,MAAM,QAAQ,OAAO,MAAM,YAAY,OAAO,MAAM,UAClE,OAAO;CAEX,IAAI,MAAM,QAAQ,CAAC,MAAM,MAAM,QAAQ,CAAC,GACpC,OAAO;CAEX,IAAI,MAAM,QAAQ,CAAC,KAAK,MAAM,QAAQ,CAAC,GACnC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,MAAM,UAAU,QAAQ,MAAM,EAAE,MAAM,CAAC;CAEpF,MAAM,OAAO;CACb,MAAM,QAAQ;CAEd,OAAO,CAAC,mBAAG,IADM,IAAI,CAAC,GAAG,OAAO,KAAK,IAAI,GAAG,GAAG,OAAO,KAAK,KAAK,CAAC,CACtD,CAAI,CAAC,CAAC,OAAO,QAAQ,QAAQ,KAAK,MAAM,MAAM,IAAI,CAAC;AAClE;;AAGA,SAAgB,aAAa,MAAc,QAAyB;CAChE,OAAO,WAAW,MAAM,SAAS,UAAU,KAAK,WAAW,GAAG,OAAM,EAAG;AAC3E"}
|
package/package.json
CHANGED
|
@@ -1,100 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@panneau/core",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "",
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
],
|
|
8
|
-
"homepage": "https://github.com/folkloreinc/panneau-js",
|
|
3
|
+
"version": "5.0.0-alpha.1",
|
|
4
|
+
"description": "The engine of Panneau: plugin registry, definition to forms and lists, form and list state, with React hooks. No UI.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
9
7
|
"repository": {
|
|
10
8
|
"type": "git",
|
|
11
|
-
"url": "git+https://github.com/folkloreinc/panneau-js.git"
|
|
12
|
-
|
|
13
|
-
"license": "ISC",
|
|
14
|
-
"author": {
|
|
15
|
-
"name": "Folklore",
|
|
16
|
-
"email": "info@folklore.email"
|
|
9
|
+
"url": "git+https://github.com/folkloreinc/panneau-js.git",
|
|
10
|
+
"directory": "packages/core"
|
|
17
11
|
},
|
|
18
|
-
"
|
|
19
|
-
{
|
|
20
|
-
"name": "David Mongeau-Petitpas",
|
|
21
|
-
"email": "dmp@folklore.email"
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
"name": "Nicolas Roy-Bourdages",
|
|
25
|
-
"email": "nrb@folklore.email"
|
|
26
|
-
}
|
|
27
|
-
],
|
|
28
|
-
"sideEffects": [
|
|
29
|
-
"**/*.css"
|
|
30
|
-
],
|
|
31
|
-
"type": "module",
|
|
12
|
+
"sideEffects": false,
|
|
32
13
|
"exports": {
|
|
33
14
|
".": {
|
|
15
|
+
"@panneau/source": "./src/index.ts",
|
|
34
16
|
"types": "./dist/index.d.ts",
|
|
35
17
|
"default": "./dist/index.js"
|
|
36
18
|
},
|
|
37
|
-
"./
|
|
38
|
-
"types": "./dist/contexts.d.ts",
|
|
39
|
-
"default": "./dist/contexts.js"
|
|
40
|
-
},
|
|
41
|
-
"./hooks": {
|
|
42
|
-
"types": "./dist/hooks.d.ts",
|
|
43
|
-
"default": "./dist/hooks.js"
|
|
44
|
-
},
|
|
45
|
-
"./utils": {
|
|
46
|
-
"types": "./dist/utils.d.ts",
|
|
47
|
-
"default": "./dist/utils.js"
|
|
48
|
-
}
|
|
19
|
+
"./package.json": "./package.json"
|
|
49
20
|
},
|
|
50
|
-
"module": "./dist/index.js",
|
|
51
|
-
"types": "./dist/index.d.ts",
|
|
52
21
|
"files": [
|
|
53
|
-
"dist"
|
|
54
|
-
"assets"
|
|
22
|
+
"dist"
|
|
55
23
|
],
|
|
56
24
|
"scripts": {
|
|
57
|
-
"build": "
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
"dependencies": {
|
|
61
|
-
"@babel/runtime": "^7.28.6",
|
|
62
|
-
"@folklore/fetch": "^0.1.21",
|
|
63
|
-
"@folklore/forms": "~0.0.30",
|
|
64
|
-
"@folklore/routes": "^0.4.11",
|
|
65
|
-
"@folklore/services": "^0.1.44",
|
|
66
|
-
"@folklore/tracking": "~0.0.34",
|
|
67
|
-
"@fortawesome/fontawesome-svg-core": "^6.5.1",
|
|
68
|
-
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
|
69
|
-
"@fortawesome/react-fontawesome": "^0.2.0",
|
|
70
|
-
"bootstrap": "^5.3.8",
|
|
71
|
-
"change-case": "^5.4.4",
|
|
72
|
-
"classnames": "^2.5.1",
|
|
73
|
-
"css-mediaquery": "^0.1.2",
|
|
74
|
-
"dayjs": "^1.10.4",
|
|
75
|
-
"debug": "^4.3.4",
|
|
76
|
-
"flat": "^6.0.1",
|
|
77
|
-
"hoist-non-react-statics": "^3.3.2",
|
|
78
|
-
"lodash-es": "^4.17.21",
|
|
79
|
-
"react-intl": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^10.0.0",
|
|
80
|
-
"react-is": "^19.2.5",
|
|
81
|
-
"slugify": "^1.5.0",
|
|
82
|
-
"snake-case": "^4.0.0",
|
|
83
|
-
"tinycolor2": "^1.4.2",
|
|
84
|
-
"webfontloader": "^1.6.28",
|
|
85
|
-
"wolfy87-eventemitter": "^5.2.9",
|
|
86
|
-
"wouter": "^3.1.2"
|
|
87
|
-
},
|
|
88
|
-
"devDependencies": {
|
|
89
|
-
"react": "^19.2.0",
|
|
90
|
-
"react-dom": "^19.0.0"
|
|
91
|
-
},
|
|
92
|
-
"peerDependencies": {
|
|
93
|
-
"react": "^19.2.0",
|
|
94
|
-
"react-dom": "^19.0.0"
|
|
25
|
+
"build": "vite build && tsc -p tsconfig.build.json",
|
|
26
|
+
"typecheck": "tsc --noEmit",
|
|
27
|
+
"api": "tsc -p tsconfig.build.json && node ../../scripts/api-report.js"
|
|
95
28
|
},
|
|
96
29
|
"publishConfig": {
|
|
97
30
|
"access": "public"
|
|
98
31
|
},
|
|
99
|
-
"
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"react": "^19.2.0"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@panneau/protocol": "5.0.0-alpha.1"
|
|
37
|
+
}
|
|
100
38
|
}
|