@jsenv/navi 0.10.2 → 0.11.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/jsenv_navi.js +13838 -23291
- package/dist/jsenv_navi.js.map +1281 -0
- package/package.json +5 -7
- package/index.js +0 -122
- package/src/action_private_properties.js +0 -11
- package/src/action_proxy_test.html +0 -353
- package/src/action_run_states.js +0 -5
- package/src/actions.js +0 -1401
- package/src/browser_integration/browser_integration.js +0 -216
- package/src/browser_integration/document_back_and_forward.js +0 -17
- package/src/browser_integration/document_loading_signal.js +0 -100
- package/src/browser_integration/document_state_signal.js +0 -9
- package/src/browser_integration/document_url_signal.js +0 -9
- package/src/browser_integration/use_is_visited.js +0 -19
- package/src/browser_integration/via_history.js +0 -232
- package/src/browser_integration/via_navigation.js +0 -168
- package/src/components/action_execution/form_context.js +0 -5
- package/src/components/action_execution/render_actionable_component.jsx +0 -29
- package/src/components/action_execution/use_action.js +0 -99
- package/src/components/action_execution/use_execute_action.js +0 -193
- package/src/components/action_execution/use_run_on_mount.js +0 -9
- package/src/components/action_renderer.jsx +0 -125
- package/src/components/callout/callout.js +0 -990
- package/src/components/callout/callout_demo.html +0 -201
- package/src/components/callout/test_dynamic_positioning.html +0 -161
- package/src/components/callout/test_html_document_iframe.html +0 -182
- package/src/components/demos/0_button_demo.html +0 -707
- package/src/components/demos/10_column_reordering_debug.html +0 -277
- package/src/components/demos/11_table_selection_debug.html +0 -432
- package/src/components/demos/1_checkbox_demo.html +0 -754
- package/src/components/demos/2_input_textual_demo.html +0 -286
- package/src/components/demos/3_radio_demo.html +0 -874
- package/src/components/demos/4_select_demo.html +0 -100
- package/src/components/demos/5_list_scrollable_demo.html +0 -153
- package/src/components/demos/6_tablist_demo.html +0 -77
- package/src/components/demos/7_table_selection_demo.html +0 -176
- package/src/components/demos/8_table_fixed_headers_demo.html +0 -584
- package/src/components/demos/9_table_column_drag_demo.html +0 -325
- package/src/components/demos/action/0_button_demo.html +0 -204
- package/src/components/demos/action/10_shortcuts_demo.html +0 -189
- package/src/components/demos/action/11_nested_shortcuts_demo.xhtml +0 -401
- package/src/components/demos/action/1_input_text_demo.html +0 -876
- package/src/components/demos/action/2_form_multiple.html +0 -303
- package/src/components/demos/action/3_details_demo.html +0 -203
- package/src/components/demos/action/4_input_checkbox_demo.html +0 -731
- package/src/components/demos/action/5_input_checkbox_state_demo.html +0 -270
- package/src/components/demos/action/6_checkbox_list_demo.html +0 -341
- package/src/components/demos/action/7_radio_list_demo.html +0 -357
- package/src/components/demos/action/8_editable_demo.html +0 -431
- package/src/components/demos/action/9_link_demo.html +0 -194
- package/src/components/demos/demo.md +0 -0
- package/src/components/demos/route/basic/basic.html +0 -14
- package/src/components/demos/route/basic/basic_route_demo.jsx +0 -224
- package/src/components/demos/route/multi/multi.html +0 -14
- package/src/components/demos/route/multi/multi_route_demo.jsx +0 -277
- package/src/components/demos/ui_transition/0_action_renderer_ui_transition_demo.html +0 -695
- package/src/components/demos/ui_transition/1_nested_ui_transition_demo.html +0 -429
- package/src/components/demos/ui_transition/2_height_transition_test.html +0 -295
- package/src/components/details/details.jsx +0 -245
- package/src/components/details/summary_marker.jsx +0 -141
- package/src/components/edition/editable.jsx +0 -186
- package/src/components/error_boundary_context.js +0 -9
- package/src/components/field/README.md +0 -247
- package/src/components/field/button.jsx +0 -429
- package/src/components/field/checkbox_list.jsx +0 -185
- package/src/components/field/collect_form_element_values.js +0 -82
- package/src/components/field/custom_field.js +0 -106
- package/src/components/field/form.jsx +0 -209
- package/src/components/field/input.jsx +0 -16
- package/src/components/field/input_checkbox.jsx +0 -434
- package/src/components/field/input_radio.jsx +0 -432
- package/src/components/field/input_textual.jsx +0 -389
- package/src/components/field/label.jsx +0 -46
- package/src/components/field/radio_list.jsx +0 -183
- package/src/components/field/select.jsx +0 -256
- package/src/components/field/use_action_events.js +0 -132
- package/src/components/field/use_form_events.js +0 -59
- package/src/components/field/use_ui_state_controller.js +0 -506
- package/src/components/item_tracker/README.md +0 -461
- package/src/components/item_tracker/use_isolated_item_tracker.jsx +0 -209
- package/src/components/item_tracker/use_isolated_item_tracker_demo.html +0 -148
- package/src/components/item_tracker/use_isolated_item_tracker_demo.jsx +0 -460
- package/src/components/item_tracker/use_item_tracker.jsx +0 -143
- package/src/components/item_tracker/use_item_tracker_demo.html +0 -207
- package/src/components/item_tracker/use_item_tracker_demo.jsx +0 -216
- package/src/components/keyboard_shortcuts/active_keyboard_shortcuts.jsx +0 -87
- package/src/components/keyboard_shortcuts/aria_key_shortcuts.js +0 -61
- package/src/components/keyboard_shortcuts/keyboard_key_meta.js +0 -17
- package/src/components/keyboard_shortcuts/keyboard_shortcuts.js +0 -371
- package/src/components/keyboard_shortcuts/os.js +0 -9
- package/src/components/layout/demos/demo_flex.html +0 -638
- package/src/components/layout/demos/demo_layout_style_buttons.html +0 -351
- package/src/components/layout/demos/demo_layout_style_input.html +0 -226
- package/src/components/layout/demos/demo_layout_style_text.html +0 -514
- package/src/components/layout/flex.jsx +0 -109
- package/src/components/layout/layout_context.jsx +0 -3
- package/src/components/layout/spacing.jsx +0 -20
- package/src/components/layout/use_layout_style.js +0 -249
- package/src/components/link/link.jsx +0 -267
- package/src/components/link/link_with_icon.jsx +0 -52
- package/src/components/loader/loader_background.jsx +0 -372
- package/src/components/loader/loading_spinner.jsx +0 -68
- package/src/components/loader/network_speed.js +0 -83
- package/src/components/loader/rectangle_loading.jsx +0 -244
- package/src/components/props_composition/demos/demo_with_props_style.html +0 -81
- package/src/components/props_composition/with_props_class_name.js +0 -37
- package/src/components/props_composition/with_props_style.js +0 -26
- package/src/components/route.jsx +0 -19
- package/src/components/selection/selection.jsx +0 -1583
- package/src/components/svg/font_sized_svg.jsx +0 -59
- package/src/components/svg/icon_and_text.jsx +0 -21
- package/src/components/svg/svg_mask_overlay.jsx +0 -105
- package/src/components/table/drag/table_drag.jsx +0 -506
- package/src/components/table/resize/table_resize.jsx +0 -650
- package/src/components/table/resize/table_size.js +0 -43
- package/src/components/table/selection/table_selection.js +0 -106
- package/src/components/table/selection/table_selection.jsx +0 -203
- package/src/components/table/sticky/sticky_group.js +0 -354
- package/src/components/table/sticky/table_sticky.js +0 -25
- package/src/components/table/sticky/table_sticky.jsx +0 -501
- package/src/components/table/table.jsx +0 -721
- package/src/components/table/table_css.js +0 -211
- package/src/components/table/table_ui.jsx +0 -49
- package/src/components/table/use_cells_and_columns.js +0 -90
- package/src/components/table/use_object_array_to_cells.js +0 -46
- package/src/components/table/z_indexes.js +0 -23
- package/src/components/tablist/tablist.jsx +0 -99
- package/src/components/text/demos/demo_text_and_icon.html +0 -421
- package/src/components/text/overflow.jsx +0 -15
- package/src/components/text/text.jsx +0 -83
- package/src/components/text/text_and_count.jsx +0 -28
- package/src/components/ui_transition.jsx +0 -128
- package/src/components/use_auto_focus.js +0 -94
- package/src/components/use_batch_during_render.js +0 -33
- package/src/components/use_debounce_true.js +0 -31
- package/src/components/use_dependencies_diff.js +0 -35
- package/src/components/use_focus_group.js +0 -20
- package/src/components/use_initial_value.js +0 -78
- package/src/components/use_is_visited.js +0 -19
- package/src/components/use_ref_array.js +0 -38
- package/src/components/use_signal_sync.js +0 -50
- package/src/components/use_stable_callback.js +0 -68
- package/src/components/use_state_array.js +0 -47
- package/src/docs/actions.md +0 -250
- package/src/docs/demos/resource/action_status.jsx +0 -42
- package/src/docs/demos/resource/demo.md +0 -1
- package/src/docs/demos/resource/resource_demo_0.html +0 -84
- package/src/docs/demos/resource/resource_demo_10_post_gc.html +0 -364
- package/src/docs/demos/resource/resource_demo_11_describe_many.html +0 -362
- package/src/docs/demos/resource/resource_demo_2.html +0 -173
- package/src/docs/demos/resource/resource_demo_3_filtered_users.html +0 -415
- package/src/docs/demos/resource/resource_demo_4_details.html +0 -284
- package/src/docs/demos/resource/resource_demo_5_renderer_lazy.html +0 -115
- package/src/docs/demos/resource/resource_demo_6_gc.html +0 -217
- package/src/docs/demos/resource/resource_demo_7_child_gc.html +0 -240
- package/src/docs/demos/resource/resource_demo_8_proxy_gc.html +0 -319
- package/src/docs/demos/resource/resource_demo_9_describe_one.html +0 -472
- package/src/docs/demos/resource/tata.jsx +0 -3
- package/src/docs/demos/resource/toto.jsx +0 -3
- package/src/docs/demos/user_nav/user_nav.html +0 -12
- package/src/docs/demos/user_nav/user_nav.jsx +0 -330
- package/src/docs/resource_dependencies.md +0 -103
- package/src/docs/resource_with_params.md +0 -80
- package/src/navi_css_vars.js +0 -14
- package/src/notes.md +0 -34
- package/src/route/route.js +0 -596
- package/src/route/route.xtest.html +0 -228
- package/src/store/array_signal_store.js +0 -537
- package/src/store/local_storage_signal.js +0 -17
- package/src/store/resource_graph.js +0 -1304
- package/src/store/tests/resource_graph_autoreload_demo.html +0 -12
- package/src/store/tests/resource_graph_autoreload_demo.jsx +0 -964
- package/src/store/tests/resource_graph_dependencies.test_manual.js +0 -95
- package/src/store/value_in_local_storage.js +0 -187
- package/src/symbol_object_signal.js +0 -1
- package/src/use_action_data.js +0 -10
- package/src/use_action_status.js +0 -47
- package/src/utils/add_many_event_listeners.js +0 -15
- package/src/utils/array_add_remove.js +0 -61
- package/src/utils/array_signal.js +0 -15
- package/src/utils/compare_two_js_values.js +0 -172
- package/src/utils/execute_with_cleanup.js +0 -21
- package/src/utils/get_caller_info.js +0 -85
- package/src/utils/is_signal.js +0 -20
- package/src/utils/js_value_weak_map.js +0 -162
- package/src/utils/js_value_weak_map_demo.html +0 -690
- package/src/utils/merge_two_js_values.js +0 -53
- package/src/utils/stringify_for_display.js +0 -131
- package/src/utils/weak_effect.js +0 -48
- package/src/validation/constraints/confirm_constraint.js +0 -14
- package/src/validation/constraints/create_unique_value_constraint.js +0 -27
- package/src/validation/constraints/native_constraints.js +0 -338
- package/src/validation/constraints/readonly_constraint.js +0 -41
- package/src/validation/constraints/same_as_constraint.js +0 -42
- package/src/validation/constraints/single_space_constraint.js +0 -13
- package/src/validation/custom_constraint_validation.js +0 -793
- package/src/validation/custom_message.js +0 -18
- package/src/validation/demos/browser_style.png +0 -0
- package/src/validation/demos/demo_same_as_constraint.html +0 -259
- package/src/validation/demos/form_validation_demo.html +0 -142
- package/src/validation/demos/form_validation_demo_preact.html +0 -87
- package/src/validation/demos/form_validation_native_popover_demo.html +0 -168
- package/src/validation/demos/form_validation_vs_native_demo.html +0 -172
- package/src/validation/hooks/use_constraints.js +0 -23
- package/src/validation/hooks/use_custom_validation_ref.js +0 -73
- package/src/validation/hooks/use_validation_message.js +0 -19
- package/src/validation/input_change_effect.js +0 -106
|
@@ -1,330 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
defineRoutes,
|
|
3
|
-
resource,
|
|
4
|
-
Route,
|
|
5
|
-
useDocumentState,
|
|
6
|
-
useDocumentUrl,
|
|
7
|
-
} from "@jsenv/navi";
|
|
8
|
-
import { signal } from "@preact/signals";
|
|
9
|
-
import { render } from "preact";
|
|
10
|
-
import { useEffect, useState } from "preact/hooks";
|
|
11
|
-
|
|
12
|
-
import.meta.css = /* css */ `
|
|
13
|
-
body {
|
|
14
|
-
font-family: Arial, sans-serif;
|
|
15
|
-
max-width: 800px;
|
|
16
|
-
margin: 0 auto;
|
|
17
|
-
padding: 20px;
|
|
18
|
-
}
|
|
19
|
-
.nav-links {
|
|
20
|
-
margin-bottom: 20px;
|
|
21
|
-
padding: 10px;
|
|
22
|
-
background: #f5f5f5;
|
|
23
|
-
border-radius: 5px;
|
|
24
|
-
}
|
|
25
|
-
.nav-links a {
|
|
26
|
-
margin-right: 15px;
|
|
27
|
-
text-decoration: none;
|
|
28
|
-
color: #007bff;
|
|
29
|
-
padding: 5px 10px;
|
|
30
|
-
border-radius: 3px;
|
|
31
|
-
}
|
|
32
|
-
.nav-links a:hover {
|
|
33
|
-
background: #e9ecef;
|
|
34
|
-
}
|
|
35
|
-
.nav-links a.active {
|
|
36
|
-
background: #007bff;
|
|
37
|
-
color: white;
|
|
38
|
-
}
|
|
39
|
-
.user-details {
|
|
40
|
-
margin: 20px 0;
|
|
41
|
-
padding: 20px;
|
|
42
|
-
border: 1px solid #ddd;
|
|
43
|
-
border-radius: 5px;
|
|
44
|
-
}
|
|
45
|
-
.actions {
|
|
46
|
-
margin-top: 15px;
|
|
47
|
-
}
|
|
48
|
-
button {
|
|
49
|
-
margin-right: 10px;
|
|
50
|
-
margin-bottom: 10px;
|
|
51
|
-
padding: 8px 15px;
|
|
52
|
-
border: none;
|
|
53
|
-
border-radius: 3px;
|
|
54
|
-
cursor: pointer;
|
|
55
|
-
background: #007bff;
|
|
56
|
-
color: white;
|
|
57
|
-
}
|
|
58
|
-
button:hover {
|
|
59
|
-
background: #0056b3;
|
|
60
|
-
}
|
|
61
|
-
button:disabled {
|
|
62
|
-
background: #6c757d;
|
|
63
|
-
cursor: not-allowed;
|
|
64
|
-
}
|
|
65
|
-
.current-url {
|
|
66
|
-
margin-top: 10px;
|
|
67
|
-
padding: 10px;
|
|
68
|
-
background: #f8f9fa;
|
|
69
|
-
border-radius: 3px;
|
|
70
|
-
font-family: monospace;
|
|
71
|
-
font-size: 14px;
|
|
72
|
-
}
|
|
73
|
-
.loading {
|
|
74
|
-
opacity: 0.6;
|
|
75
|
-
}
|
|
76
|
-
.error {
|
|
77
|
-
color: #dc3545;
|
|
78
|
-
background: #f8d7da;
|
|
79
|
-
padding: 10px;
|
|
80
|
-
border-radius: 3px;
|
|
81
|
-
}
|
|
82
|
-
`;
|
|
83
|
-
|
|
84
|
-
const App = () => {
|
|
85
|
-
return (
|
|
86
|
-
<div>
|
|
87
|
-
<h1>User Navigation Test</h1>
|
|
88
|
-
<Navigation />
|
|
89
|
-
<Route route={USER_ROUTE}>{(user) => <UserPage user={user} />}</Route>
|
|
90
|
-
<DocumentInfo />
|
|
91
|
-
</div>
|
|
92
|
-
);
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
const Navigation = () => {
|
|
96
|
-
const users = USER.useArray();
|
|
97
|
-
|
|
98
|
-
return (
|
|
99
|
-
<div className="nav-links">
|
|
100
|
-
{users.map((user) => {
|
|
101
|
-
const url = USER_ROUTE.buildUrl({ name: user.name });
|
|
102
|
-
return (
|
|
103
|
-
<a key={user.id} href={url}>
|
|
104
|
-
{user.name}
|
|
105
|
-
</a>
|
|
106
|
-
);
|
|
107
|
-
})}
|
|
108
|
-
</div>
|
|
109
|
-
);
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
const UserPage = ({ user }) => {
|
|
113
|
-
const isRenamed = user.name !== user.originalName;
|
|
114
|
-
|
|
115
|
-
const handleRename = async () => {
|
|
116
|
-
console.log("handleRename called for user:", user.name);
|
|
117
|
-
const renameAction = USER.PUT.bindParams({
|
|
118
|
-
name: user.name,
|
|
119
|
-
property: "name",
|
|
120
|
-
value: `${user.name}_2`,
|
|
121
|
-
});
|
|
122
|
-
console.log("About to call renameAction.load()");
|
|
123
|
-
await renameAction.reload();
|
|
124
|
-
console.log("renameAction.load() completed");
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
const handleRevert = async () => {
|
|
128
|
-
const revertAction = USER.PUT.bindParams({
|
|
129
|
-
name: user.name,
|
|
130
|
-
property: "name",
|
|
131
|
-
value: user.originalName,
|
|
132
|
-
});
|
|
133
|
-
await revertAction.reload();
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
return (
|
|
137
|
-
<div className="user-details">
|
|
138
|
-
<h2>User: {user.name}</h2>
|
|
139
|
-
<p>
|
|
140
|
-
<strong>Status:</strong> {isRenamed ? "Renamed" : "Original"}
|
|
141
|
-
</p>
|
|
142
|
-
|
|
143
|
-
<div className="actions">
|
|
144
|
-
<button
|
|
145
|
-
onClick={handleRename}
|
|
146
|
-
disabled={USER.PUT.loadingState === "LOADING"}
|
|
147
|
-
>
|
|
148
|
-
Rename to "{user.name}_2"
|
|
149
|
-
</button>
|
|
150
|
-
<button
|
|
151
|
-
onClick={handleRevert}
|
|
152
|
-
disabled={!isRenamed || USER.PUT.loadingState === "LOADING"}
|
|
153
|
-
>
|
|
154
|
-
Revert to Original Name
|
|
155
|
-
</button>
|
|
156
|
-
</div>
|
|
157
|
-
|
|
158
|
-
<MutableIdSignalDemo currentUser={user} />
|
|
159
|
-
</div>
|
|
160
|
-
);
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
const MutableIdSignalDemo = ({ currentUser }) => {
|
|
164
|
-
// Create a signal that tracks the ORIGINAL user's name (this should NOT change)
|
|
165
|
-
const [originalName] = useState(currentUser.name);
|
|
166
|
-
const originalUserNameSignal = signal(originalName);
|
|
167
|
-
|
|
168
|
-
// Use signalForMutableIdKey to get a signal that tracks the user by the ORIGINAL name
|
|
169
|
-
const userFromMutableIdSignal = USER.store.signalForMutableIdKey(
|
|
170
|
-
"name",
|
|
171
|
-
originalUserNameSignal,
|
|
172
|
-
);
|
|
173
|
-
|
|
174
|
-
// Get the current value
|
|
175
|
-
const [signalValue, setSignalValue] = useState(userFromMutableIdSignal.value);
|
|
176
|
-
|
|
177
|
-
// Subscribe to changes
|
|
178
|
-
useEffect(() => {
|
|
179
|
-
console.log(
|
|
180
|
-
"MutableIdSignalDemo: Setting up subscription to userFromMutableIdSignal",
|
|
181
|
-
);
|
|
182
|
-
const unsubscribe = userFromMutableIdSignal.subscribe((newValue) => {
|
|
183
|
-
console.log(
|
|
184
|
-
"MutableIdSignalDemo: userFromMutableIdSignal changed to:",
|
|
185
|
-
newValue,
|
|
186
|
-
);
|
|
187
|
-
setSignalValue(newValue);
|
|
188
|
-
});
|
|
189
|
-
return unsubscribe;
|
|
190
|
-
}, []);
|
|
191
|
-
|
|
192
|
-
console.log("MutableIdSignalDemo render:", {
|
|
193
|
-
originalName,
|
|
194
|
-
currentUserName: currentUser.name,
|
|
195
|
-
currentUserId: currentUser.id,
|
|
196
|
-
signalValueName: signalValue?.name,
|
|
197
|
-
signalValueId: signalValue?.id,
|
|
198
|
-
originalUserNameSignalValue: originalUserNameSignal.value,
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
// Check if a rename has occurred
|
|
202
|
-
const hasBeenRenamed = currentUser.name !== originalName;
|
|
203
|
-
|
|
204
|
-
return (
|
|
205
|
-
<div
|
|
206
|
-
style={{
|
|
207
|
-
marginTop: "20px",
|
|
208
|
-
padding: "15px",
|
|
209
|
-
backgroundColor: "#f0f8ff",
|
|
210
|
-
borderRadius: "5px",
|
|
211
|
-
border: "1px solid #007bff",
|
|
212
|
-
}}
|
|
213
|
-
>
|
|
214
|
-
<h3>signalForMutableIdKey Demo</h3>
|
|
215
|
-
<p>
|
|
216
|
-
<strong>Current Route User:</strong> {currentUser.name} (ID:{" "}
|
|
217
|
-
{currentUser.id})
|
|
218
|
-
</p>
|
|
219
|
-
<p>
|
|
220
|
-
<strong>Signal Tracking Original Name:</strong>{" "}
|
|
221
|
-
{originalUserNameSignal.value}
|
|
222
|
-
</p>
|
|
223
|
-
<p>
|
|
224
|
-
<strong>Signal Value:</strong>{" "}
|
|
225
|
-
{signalValue ? `${signalValue.name} (ID: ${signalValue.id})` : "null"}
|
|
226
|
-
</p>
|
|
227
|
-
<p style={{ fontSize: "0.9em", color: "#666" }}>
|
|
228
|
-
💡 This signal tracks by the original name "{originalName}"
|
|
229
|
-
but should return the same user even after renaming, demonstrating the
|
|
230
|
-
caching behavior of signalForMutableIdKey.
|
|
231
|
-
</p>
|
|
232
|
-
{signalValue && signalValue.id === currentUser.id && hasBeenRenamed && (
|
|
233
|
-
<p style={{ color: "green", fontWeight: "bold" }}>
|
|
234
|
-
✅ Signal correctly returns the same user instance even after rename!
|
|
235
|
-
</p>
|
|
236
|
-
)}
|
|
237
|
-
{signalValue && signalValue.id === currentUser.id && !hasBeenRenamed && (
|
|
238
|
-
<p style={{ color: "blue", fontWeight: "bold" }}>
|
|
239
|
-
🔵 Signal correctly returns the user (no rename yet)
|
|
240
|
-
</p>
|
|
241
|
-
)}
|
|
242
|
-
{signalValue && signalValue.id !== currentUser.id && (
|
|
243
|
-
<p style={{ color: "orange", fontWeight: "bold" }}>
|
|
244
|
-
⚠️ Signal returned a different user (this might happen during
|
|
245
|
-
transitions)
|
|
246
|
-
</p>
|
|
247
|
-
)}
|
|
248
|
-
{!signalValue && (
|
|
249
|
-
<p style={{ color: "red", fontWeight: "bold" }}>
|
|
250
|
-
❌ Signal returned null (user not found in store) - Looking for
|
|
251
|
-
original name: "{originalUserNameSignal.value}"
|
|
252
|
-
</p>
|
|
253
|
-
)}
|
|
254
|
-
</div>
|
|
255
|
-
);
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
const DocumentInfo = () => {
|
|
259
|
-
const documentUrl = useDocumentUrl();
|
|
260
|
-
const documentState = useDocumentState();
|
|
261
|
-
|
|
262
|
-
return (
|
|
263
|
-
<div>
|
|
264
|
-
<div>
|
|
265
|
-
Current URL: <div className="current-url">{documentUrl}</div>
|
|
266
|
-
</div>
|
|
267
|
-
<div className="current-state">
|
|
268
|
-
Current State: <pre>{JSON.stringify(documentState, null, 2)}</pre>
|
|
269
|
-
</div>
|
|
270
|
-
</div>
|
|
271
|
-
);
|
|
272
|
-
};
|
|
273
|
-
|
|
274
|
-
const initialUsers = [
|
|
275
|
-
{
|
|
276
|
-
id: 1,
|
|
277
|
-
name: "alice",
|
|
278
|
-
email: "alice@example.com",
|
|
279
|
-
originalName: "alice",
|
|
280
|
-
},
|
|
281
|
-
{
|
|
282
|
-
id: 2,
|
|
283
|
-
name: "bob",
|
|
284
|
-
email: "bob@example.com",
|
|
285
|
-
originalName: "bob",
|
|
286
|
-
},
|
|
287
|
-
{
|
|
288
|
-
id: 3,
|
|
289
|
-
name: "charlie",
|
|
290
|
-
email: "charlie@example.com",
|
|
291
|
-
originalName: "charlie",
|
|
292
|
-
},
|
|
293
|
-
];
|
|
294
|
-
const USER = resource("user", {
|
|
295
|
-
idKey: "id",
|
|
296
|
-
mutableIdKeys: ["name"],
|
|
297
|
-
GET_MANY: () => initialUsers,
|
|
298
|
-
GET: async ({ name }) => {
|
|
299
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
300
|
-
return initialUsers.find((user) => user.name === name);
|
|
301
|
-
},
|
|
302
|
-
PUT: ({ name, property, value }) => {
|
|
303
|
-
console.log("PUT action called:", { name, property, value });
|
|
304
|
-
const userIndex = initialUsers.findIndex((user) => user.name === name);
|
|
305
|
-
if (userIndex === -1) {
|
|
306
|
-
throw new Error(`User with name "${name}" not found`);
|
|
307
|
-
}
|
|
308
|
-
const user = initialUsers[userIndex];
|
|
309
|
-
console.log("Found user:", user);
|
|
310
|
-
const updatedUser = {
|
|
311
|
-
...user,
|
|
312
|
-
[property]: value,
|
|
313
|
-
};
|
|
314
|
-
console.log("Updated user:", updatedUser);
|
|
315
|
-
|
|
316
|
-
// Update the initialUsers array so future lookups work
|
|
317
|
-
initialUsers[userIndex] = updatedUser;
|
|
318
|
-
|
|
319
|
-
return updatedUser;
|
|
320
|
-
},
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
const [USER_ROUTE] = defineRoutes({
|
|
324
|
-
"/user/:name": USER.GET,
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
// Populate initial users in the store
|
|
328
|
-
USER.store.upsert(initialUsers);
|
|
329
|
-
|
|
330
|
-
render(<App />, document.querySelector("#app"));
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
# Resource Dependencies Documentation
|
|
2
|
-
|
|
3
|
-
The `withParams` method now supports cross-resource dependencies, allowing you to set up autoreload relationships between different resources.
|
|
4
|
-
|
|
5
|
-
## Basic Usage
|
|
6
|
-
|
|
7
|
-
```js
|
|
8
|
-
const role = resource("role", {
|
|
9
|
-
GET_MANY: () => fetchRoles(),
|
|
10
|
-
POST: (data) => createRole(data),
|
|
11
|
-
DELETE: (id) => deleteRole(id),
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
const database = resource("database", {
|
|
15
|
-
GET_MANY: () => fetchDatabases(),
|
|
16
|
-
POST: (data) => createDatabase(data),
|
|
17
|
-
DELETE: (id) => deleteDatabase(id),
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
const tables = resource("tables", {
|
|
21
|
-
GET_MANY: () => fetchTables(),
|
|
22
|
-
POST: (data) => createTable(data),
|
|
23
|
-
DELETE: (id) => deleteTable(id),
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
// Create a parameterized resource with cross-resource dependencies
|
|
27
|
-
const ROLE_WITH_OWNERSHIP = role.withParams(
|
|
28
|
-
{ owners: true },
|
|
29
|
-
{
|
|
30
|
-
dependencies: [role, database, tables],
|
|
31
|
-
},
|
|
32
|
-
);
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## How It Works
|
|
36
|
-
|
|
37
|
-
When you specify `dependencies`, any non-GET action (POST, PUT, PATCH, DELETE) on the dependency resources will trigger an autoreload of the GET_MANY actions in the parameterized resource.
|
|
38
|
-
|
|
39
|
-
### Autoreload Behavior
|
|
40
|
-
|
|
41
|
-
- **Triggering Actions**: Any POST, PUT, PATCH, or DELETE on dependency resources
|
|
42
|
-
- **Target Actions**: GET_MANY actions in the parameterized resource (same param scope only)
|
|
43
|
-
- **Scope Isolation**: Only actions with the same parameter scope are affected
|
|
44
|
-
|
|
45
|
-
### Example Scenarios
|
|
46
|
-
|
|
47
|
-
1. **Creating a table**: `tables.POST.load(newTableData)` → triggers `ROLE_WITH_OWNERSHIP.GET_MANY` reload
|
|
48
|
-
2. **Deleting a database**: `database.DELETE.load(dbId)` → triggers `ROLE_WITH_OWNERSHIP.GET_MANY` reload
|
|
49
|
-
3. **Updating a role**: `role.PUT.load(roleData)` → triggers `ROLE_WITH_OWNERSHIP.GET_MANY` reload
|
|
50
|
-
|
|
51
|
-
## Advanced Usage
|
|
52
|
-
|
|
53
|
-
### Parameterized Dependencies
|
|
54
|
-
|
|
55
|
-
You can also use parameterized resources as dependencies:
|
|
56
|
-
|
|
57
|
-
```js
|
|
58
|
-
const recentTables = tables.withParams({ recent: true });
|
|
59
|
-
const adminTables = tables.withParams({ owner: "admin" });
|
|
60
|
-
|
|
61
|
-
const ROLE_WITH_RECENT_OWNERSHIP = role.withParams(
|
|
62
|
-
{ owners: true },
|
|
63
|
-
{
|
|
64
|
-
dependencies: [recentTables], // Only affected by recent tables
|
|
65
|
-
},
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
const ROLE_WITH_ADMIN_OWNERSHIP = role.withParams(
|
|
69
|
-
{ owners: true },
|
|
70
|
-
{
|
|
71
|
-
dependencies: [adminTables], // Only affected by admin tables
|
|
72
|
-
},
|
|
73
|
-
);
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### Custom Autoreload Settings
|
|
77
|
-
|
|
78
|
-
You can also customize the autoreload behavior:
|
|
79
|
-
|
|
80
|
-
```js
|
|
81
|
-
const ROLE_WITH_OWNERSHIP = role.withParams(
|
|
82
|
-
{ owners: true },
|
|
83
|
-
{
|
|
84
|
-
dependencies: [role, database, tables],
|
|
85
|
-
autoreloadGetManyAfter: ["POST", "DELETE", "PUT"], // Custom trigger verbs
|
|
86
|
-
autoreloadGetAfter: false, // Disable GET autoreload
|
|
87
|
-
},
|
|
88
|
-
);
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
## Implementation Details
|
|
92
|
-
|
|
93
|
-
- **Global Registry**: Dependencies are tracked in a global registry to enable cross-resource communication
|
|
94
|
-
- **Memory Management**: The system uses WeakSets to avoid memory leaks
|
|
95
|
-
- **Async Execution**: Autoreloads are triggered asynchronously with `setTimeout` to ensure proper sequencing
|
|
96
|
-
- **Parameter Isolation**: Each parameter scope maintains its own autoreload behavior
|
|
97
|
-
|
|
98
|
-
## Benefits
|
|
99
|
-
|
|
100
|
-
1. **Reactive Updates**: Automatically keep related data in sync across different resources
|
|
101
|
-
2. **Parameter Isolation**: Avoid unwanted cross-contamination between different parameter sets
|
|
102
|
-
3. **Flexible Dependencies**: Mix and match regular and parameterized resources as dependencies
|
|
103
|
-
4. **Performance**: Only reload what's actually needed based on the dependency graph
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# Resource `withParams()` Method
|
|
2
|
-
|
|
3
|
-
Creates a parameterized version of a resource with isolated autoreload behavior. Solves cross-contamination where actions with different parameters incorrectly trigger each other's autoreload.
|
|
4
|
-
|
|
5
|
-
## Problem & Solution
|
|
6
|
-
|
|
7
|
-
Without `withParams()`:
|
|
8
|
-
|
|
9
|
-
```javascript
|
|
10
|
-
const ROLE = resource("role", {
|
|
11
|
-
GET_MANY: (params) => fetchRoles(params),
|
|
12
|
-
DELETE: (params) => deleteRole(params),
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
// These actions interfere with each other
|
|
16
|
-
await ROLE.GET_MANY.bindParams({ admin: true });
|
|
17
|
-
await ROLE.DELETE.bindParams({ id: 123 }); // ❌ Reloads both admin and non-admin queries
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
With `withParams()`:
|
|
21
|
-
|
|
22
|
-
```javascript
|
|
23
|
-
const adminRoles = ROLE.withParams({ admin: true });
|
|
24
|
-
const guestRoles = ROLE.withParams({ admin: false });
|
|
25
|
-
|
|
26
|
-
await adminRoles.DELETE({ id: 123 }); // ✅ Only reloads admin queries
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## API
|
|
30
|
-
|
|
31
|
-
### `resource.withParams(params)`
|
|
32
|
-
|
|
33
|
-
**Parameters:** `params` (Object, required) - Parameters to bind to all actions
|
|
34
|
-
|
|
35
|
-
**Returns:** New resource instance with parameter-bound actions and isolated autoreload
|
|
36
|
-
|
|
37
|
-
**Throws:** Error if params is empty
|
|
38
|
-
|
|
39
|
-
## Autoreload Hierarchy
|
|
40
|
-
|
|
41
|
-
Actions follow a parent-child hierarchy where child scopes reload their parents:
|
|
42
|
-
|
|
43
|
-
```javascript
|
|
44
|
-
const ROLE = resource("role", { GET_MANY: () => fetch("/roles") });
|
|
45
|
-
const ROLE_ADMIN = ROLE.withParams({ type: "admin" });
|
|
46
|
-
const ROLE_ADMIN_MALE = ROLE_ADMIN.withParams({ gender: "male" });
|
|
47
|
-
|
|
48
|
-
// Si ROLE_ADMIN_MALE.POST() est exécuté, il recharge :
|
|
49
|
-
// ✅ ROLE_ADMIN_MALE.GET_MANY (même scope: { type: "admin", gender: "male" })
|
|
50
|
-
// ✅ ROLE_ADMIN.GET_MANY (parent scope: { type: "admin" })
|
|
51
|
-
// ✅ ROLE.GET_MANY (root parent: {})
|
|
52
|
-
// ❌ Ne recharge PAS femaleAdmin.GET_MANY ({ type: "admin", gender: "female" })
|
|
53
|
-
|
|
54
|
-
// Si ROLE_ADMIN.POST() est exécuté, il recharge :
|
|
55
|
-
// ✅ ROLE_ADMIN.GET_MANY (même scope: { type: "admin" })
|
|
56
|
-
// ✅ ROLE.GET_MANY (root parent: {})
|
|
57
|
-
// ❌ Ne recharge PAS ROLE_ADMIN_MALE.GET_MANY (enfant, pas parent)
|
|
58
|
-
|
|
59
|
-
// Si ROLE.POST() est exécuté, il recharge :
|
|
60
|
-
// ✅ ROLE.GET_MANY (même scope: {})
|
|
61
|
-
// ❌ Ne recharge PAS ROLE_ADMIN.GET_MANY ni ROLE_ADMIN_MALE.GET_MANY (enfants, pas parents)
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
## Chaining
|
|
65
|
-
|
|
66
|
-
```javascript
|
|
67
|
-
const maleAdmins = USER.withParams({ role: "admin" }).withParams({
|
|
68
|
-
gender: "male",
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
// Equivalent to:
|
|
72
|
-
const maleAdmins = USER.withParams({ role: "admin", gender: "male" });
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
## Key Features
|
|
76
|
-
|
|
77
|
-
- **Isolation**: Different parameter sets have separate autoreload behavior
|
|
78
|
-
- **Hierarchy**: Child scopes reload parent scopes automatically
|
|
79
|
-
- **Shared Store**: All parameterized resources use the same data store
|
|
80
|
-
- **Efficient**: Parameter comparison is cached for performance
|
package/src/navi_css_vars.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import.meta.css = /* css */ `
|
|
2
|
-
@layer navi {
|
|
3
|
-
:root {
|
|
4
|
-
--navi-background-color-readonly: #d3d3d3;
|
|
5
|
-
--navi-color-readonly: grey;
|
|
6
|
-
--navi-background-color-disabled: #d3d3d3;
|
|
7
|
-
--navi-color-disabled: #eeeeee;
|
|
8
|
-
|
|
9
|
-
--navi-info-color: #2196f3;
|
|
10
|
-
--navi-warning-color: #ff9800;
|
|
11
|
-
--navi-error-color: #f44336;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
`;
|
package/src/notes.md
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
- Drag to move row and column
|
|
2
|
-
|
|
3
|
-
(ideally we keep an empty "clone" in the table and we create a visually identic clone to drag)
|
|
4
|
-
|
|
5
|
-
sitcky prevents drag to re-order
|
|
6
|
-
I think we are starting to reach the limits of a table element
|
|
7
|
-
|
|
8
|
-
donc on va refaire mais avec des div comme ca on controle bien tout
|
|
9
|
-
de toute facon les dimensions des lignes et colonnes seront fixes
|
|
10
|
-
et je gagne pas grand chose a passer par la balise table
|
|
11
|
-
|
|
12
|
-
- Ideally the drag gesture should autoscroll once dragged element boundaries reach the scrollable parent (not the mouse)
|
|
13
|
-
|
|
14
|
-
- Can use shortcuts on table selection
|
|
15
|
-
- cmd + delete would delete rows/columns
|
|
16
|
-
on cells it does nothing but we'll be able to copy via keyboard to start
|
|
17
|
-
|
|
18
|
-
- Fixed first column and first row (overflow on the rest + it's fixed when there is a lof of content)
|
|
19
|
-
|
|
20
|
-
- Can delete a table row
|
|
21
|
-
|
|
22
|
-
- Can update a table row cell
|
|
23
|
-
|
|
24
|
-
- Can see table columns attributes
|
|
25
|
-
|
|
26
|
-
- Can update table column attributes
|
|
27
|
-
|
|
28
|
-
- Can remove table column
|
|
29
|
-
|
|
30
|
-
- Can move table column
|
|
31
|
-
|
|
32
|
-
- Pagination
|
|
33
|
-
|
|
34
|
-
- import.meta.css during build should use stylesheet to inject so that it puts an url instead of constructed stylesheet?
|