sdc_client 0.158.9 → 0.159.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/LICENSE +21 -0
  3. package/dist/index.js +23 -13
  4. package/dist/ugly.index.js +2 -1
  5. package/dist/ugly.index.js.LICENSE.txt +1 -8
  6. package/gulp/gulp.jsx +11 -36
  7. package/package.json +22 -11
  8. package/src/index.js +27 -7
  9. package/src/simpleDomControl/AbstractSDC.js +15 -11
  10. package/src/simpleDomControl/sdc_controller.js +3 -3
  11. package/src/simpleDomControl/sdc_dom_events.js +5 -10
  12. package/src/simpleDomControl/sdc_events.js +3 -3
  13. package/src/simpleDomControl/sdc_main.js +34 -13
  14. package/src/simpleDomControl/sdc_model.js +209 -84
  15. package/src/simpleDomControl/sdc_params.js +0 -3
  16. package/src/simpleDomControl/sdc_server_call.js +21 -4
  17. package/src/simpleDomControl/sdc_test_utils.js +0 -1
  18. package/src/simpleDomControl/sdc_utils.js +59 -7
  19. package/src/simpleDomControl/sdc_view.js +16 -1
  20. package/.github/workflows/node.js.yml +0 -38
  21. package/.idea/inspectionProfiles/Project_Default.xml +0 -17
  22. package/.idea/jsLibraryMappings.xml +0 -6
  23. package/.idea/misc.xml +0 -6
  24. package/.idea/modules.xml +0 -8
  25. package/.idea/vcs.xml +0 -6
  26. package/.idea/workspace.xml +0 -403
  27. package/.readthedocs.yaml +0 -13
  28. package/.tool-versions +0 -1
  29. package/SimpleDomControlClient.iml +0 -12
  30. package/docs/api-reference.rst +0 -225
  31. package/docs/conf.py +0 -11
  32. package/docs/controllers.rst +0 -228
  33. package/docs/events-and-dom.rst +0 -120
  34. package/docs/getting-started.rst +0 -143
  35. package/docs/index.rst +0 -22
  36. package/docs/models.rst +0 -351
  37. package/docs/overview.rst +0 -66
  38. package/docs/requirements.txt +0 -1
  39. package/eslint.config.js +0 -43
  40. package/gulpfile.cjs +0 -30
  41. package/jest.config.mjs +0 -197
  42. package/test/controller.test.js +0 -93
  43. package/test/dist.test.js +0 -127
  44. package/test/model.test.js +0 -330
  45. package/test/models/Author.js +0 -145
  46. package/test/models/Book.js +0 -112
  47. package/test/models/BookContent.js +0 -114
  48. package/test/models/SdcUser.js +0 -75
  49. package/test/models/src.js +0 -8
  50. package/test/sdc_model_dates.ai.test.js +0 -57
  51. package/test/sdc_server_call.ai.test.js +0 -267
  52. package/test/utils.js +0 -88
  53. package/test/view.test.js +0 -159
  54. package/test-setup.js +0 -4
  55. package/webpack.config/webpack.default.config.cjs +0 -14
  56. package/webpack.config/webpack.development.config.cjs +0 -14
  57. package/webpack.config/webpack.production.config.cjs +0 -11
@@ -1,225 +0,0 @@
1
- API Reference
2
- =============
3
-
4
- Top-level exports
5
- -----------------
6
-
7
- The package entry point exports the following public API:
8
-
9
- ``app``
10
- Global runtime object.
11
-
12
- ``AbstractSDC``
13
- Base controller class.
14
-
15
- ``SdcModel``
16
- Model base export from ``sdc_model.js``.
17
-
18
- ``SdcQuerySet``
19
- QuerySet collection class for backend-backed models.
20
-
21
- ``registerModel(name, classObj)``
22
- Registers a model class in the global model registry.
23
-
24
- ``on(name, controller)``
25
- Registers a controller or object as a listener for an application event.
26
-
27
- ``trigger(name, ...args)``
28
- Emits an application event and returns a promise of listener results.
29
-
30
- ``allOff(controller)``
31
- Removes the controller from all application event subscriptions.
32
-
33
- ``setEvent(name, functionName = name)``
34
- Maps an application event name to a handler method name.
35
-
36
- ``clearErrorsInForm($form)``
37
- Removes form-level and field-level validation error markup.
38
-
39
- ``setErrorsInForm($form, $resForm)``
40
- Applies validation error markup from a response form fragment.
41
-
42
- ``checkIfParamNumberBoolOrString(value, controller = null)``
43
- Converts serialized DOM values into typed JavaScript values.
44
-
45
- ``controllerFactory(parentController, $element, tagName, superTagNameList)``
46
- Creates a controller instance for a registered tag.
47
-
48
- ``runControlFlowFunctions(controller, process)``
49
- Runs ``onLoad()``, child rendering, ``willShow()``, and refresh.
50
-
51
- ``socketReconnect``
52
- Alias of the server-call ``close()`` function.
53
-
54
- ``test_utils``
55
- Test helpers: ``get_controller()``, ``getCsrfToken()``,
56
- ``controllerFromTestHtml()``.
57
-
58
- ``app`` reference
59
- -----------------
60
-
61
- Bootstrap and registration
62
- ^^^^^^^^^^^^^^^^^^^^^^^^^^
63
-
64
- ``app.init_sdc()``
65
- Initializes the runtime, scans the DOM, and instantiates registered
66
- controllers.
67
-
68
- ``app.register(Controller, overwrite = false)``
69
- Registers a controller class and returns an object with ``addMixin(...)``.
70
-
71
- ``app.registerGlobal(Controller)``
72
- Registers a controller and marks it as global.
73
-
74
- ``app.controllerToTag(Controller)``
75
- Converts a controller class name to a tag name.
76
-
77
- DOM and controller helpers
78
- ^^^^^^^^^^^^^^^^^^^^^^^^^^
79
-
80
- ``app.getController($elem)``
81
- Returns the controller bound to a DOM node or its closest controller parent.
82
-
83
- ``app.refresh($dom, leafController = null)``
84
- Refreshes the controller subtree rooted at the given node.
85
-
86
- ``app.reloadController(controller)``
87
- Reloads controller HTML from ``contentUrl`` and reconciles it into place.
88
-
89
- ``app.reconcile(controller, $virtualNode, $realNode = null, process = null)``
90
- Runs refresh and DOM reconciliation for a controller.
91
-
92
- ``app.cleanCache()``
93
- Clears cached HTML fragments loaded from controller ``contentUrl`` values.
94
-
95
- ``app.updateJquery()``
96
- Installs ``safeReplace()``, ``safeEmpty()``, and ``safeRemove()`` on jQuery.
97
-
98
- Safe DOM operations
99
- ^^^^^^^^^^^^^^^^^^^
100
-
101
- ``app.safeRemove($elem)``
102
- Removes DOM nodes after cleanly removing any controllers contained in them.
103
-
104
- ``app.safeEmpty($elem)``
105
- Safely removes all children of a container.
106
-
107
- ``app.safeReplace($elem, $new)``
108
- Inserts ``$new`` before ``$elem`` and safely removes ``$elem``.
109
-
110
- HTTP and form helpers
111
- ^^^^^^^^^^^^^^^^^^^^^
112
-
113
- ``app.get(controller, url, args)``
114
- GET request wrapper that refreshes the controller on success.
115
-
116
- ``app.post(controller, url, args)``
117
- POST request wrapper that refreshes the controller on success.
118
-
119
- ``app.ajax(controller, url, args, method)``
120
- Shared transport wrapper for ``get`` and ``post``.
121
-
122
- ``app.submitFormAndUpdateView(controller, form, url, method)``
123
- Submits a form, then refreshes the controller when successful.
124
-
125
- ``app.submitForm(form, url, method)``
126
- Submits a form without a controller refresh step.
127
-
128
- ``AbstractSDC`` reference
129
- -------------------------
130
-
131
- Tree and DOM
132
- ^^^^^^^^^^^^
133
-
134
- ``find(selector)``
135
- Shortcut for ``this.$container.find(selector)``.
136
-
137
- ``refresh()``
138
- Refreshes the controller subtree.
139
-
140
- ``reload()``
141
- Reloads controller HTML from the backend.
142
-
143
- ``reconcile($virtualNode, $realNode = null)``
144
- Reconciles virtual HTML into the controller's real DOM.
145
-
146
- ``iterateAllChildren()``
147
- Recursively returns all descendant controllers.
148
-
149
- Lifecycle
150
- ^^^^^^^^^
151
-
152
- ``onInit(...args)``
153
- ``onLoad(html)``
154
- ``willShow()``
155
- ``onRefresh(originController)``
156
- ``onRemove()``
157
-
158
- Networking and models
159
- ^^^^^^^^^^^^^^^^^^^^^
160
-
161
- ``get(url, args)``
162
- ``post(url, args)``
163
- ``submitForm(form, url, method)``
164
- ``serverCall(methodName, args)``
165
- ``querySet(modelName, modelQuery = {})``
166
- ``noOpenModelRequests()``
167
-
168
- Forms
169
- ^^^^^
170
-
171
- ``submitModelFormDistributor($form, event)``
172
- ``defaultSubmitModelForm($form, event)``
173
-
174
- ``SdcQuerySet`` reference
175
- -------------------------
176
-
177
- Collection API
178
- ^^^^^^^^^^^^^^
179
-
180
- ``length``
181
- ``[index]``
182
- ``[Symbol.iterator]()``
183
- ``getIds()``
184
- ``setIds(ids)``
185
- ``byId(id)``
186
- ``new()``
187
-
188
- Query and transport
189
- ^^^^^^^^^^^^^^^^^^^
190
-
191
- ``setFilter(modelQuery)``
192
- ``addFilter(modelQuery)``
193
- ``load(modelQuery = null)``
194
- ``update({ modelQuery = null, item = null })``
195
- ``get(modelQuery = null)``
196
- ``delete({ pk = null, elem = null })``
197
- ``save({ pk = null, formName = "edit_form", data = null })``
198
- ``create({ elem, data = null })``
199
- ``isConnected()``
200
- ``close()``
201
- ``noOpenRequests()``
202
-
203
- View rendering
204
- ^^^^^^^^^^^^^^
205
-
206
- ``view({ viewName = "html_list_template", modelQuery = {}, cbResolve = null,
207
- cbReject = null, templateContext = {}, eventType = "named_view" })``
208
-
209
- ``listView({ modelQuery = {}, cbResolve = null, cbReject = null,
210
- templateContext = {} })``
211
-
212
- ``detailView({ pk, cbResolve = null, cbReject = null, templateContext = {} })``
213
-
214
- Test utilities
215
- --------------
216
-
217
- ``getCsrfToken()``
218
- Reads the ``csrftoken`` cookie in test environments.
219
-
220
- ``get_controller(tag_name, init_arguments = {}, origen_html = "")``
221
- Creates a controller through the normal SDC lifecycle in a JSDOM test.
222
-
223
- ``controllerFromTestHtml(html, afterLifecycle = null)``
224
- Bootstraps controllers from arbitrary test HTML and returns the resulting
225
- controller list.
package/docs/conf.py DELETED
@@ -1,11 +0,0 @@
1
- project = "SimpleDomControlClient"
2
- author = "Martin Starman"
3
- copyright = "2026, Martin Starman"
4
- release = "0.58.6"
5
-
6
- extensions = []
7
- templates_path = ["_templates"]
8
- exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
9
-
10
- html_theme = "alabaster"
11
- html_static_path = ["_static"]
@@ -1,228 +0,0 @@
1
- Controllers
2
- ===========
3
-
4
- Base class
5
- ----------
6
-
7
- All controllers extend ``AbstractSDC``.
8
-
9
- Common properties
10
- -----------------
11
-
12
- ``contentUrl``
13
- Backend URL used to load the controller's HTML fragment.
14
-
15
- ``contentReload``
16
- If ``true``, the content is always reloaded instead of using the cached
17
- HTML fragment.
18
-
19
- ``events``
20
- List of event definition objects merged into one event map.
21
-
22
- ``load_async``
23
- If ``true``, the controller lifecycle does not block parent initialization.
24
-
25
- ``$container``
26
- jQuery wrapper for the DOM element associated with the controller.
27
-
28
- ``parentController`` / ``childController``
29
- Accessors for the controller tree.
30
-
31
- Lifecycle
32
- ---------
33
-
34
- ``onInit(...args)``
35
- Runs immediately after the controller is created. Arguments are resolved
36
- from DOM ``data-*`` attributes.
37
-
38
- ``onLoad(html)``
39
- Runs after the controller HTML has been fetched but before child controller
40
- tags are replaced. This is a common place to mutate the loaded fragment.
41
-
42
- ``willShow()``
43
- Runs after child controller content has been prepared and before refresh.
44
-
45
- ``onRefresh(originController)``
46
- Runs after DOM updates and event wiring are complete.
47
-
48
- ``onRemove()``
49
- Runs when the controller is being removed. Return ``false`` to block
50
- removal.
51
-
52
- Example lifecycle
53
- -----------------
54
-
55
- .. code-block:: javascript
56
-
57
- class ProductList extends AbstractSDC {
58
- constructor() {
59
- super();
60
- this.contentUrl = "/sdc_view/shop/product-list/";
61
- }
62
-
63
- onInit(categoryId) {
64
- this.categoryId = categoryId;
65
- }
66
-
67
- onLoad(html) {
68
- $(html).find(".title").text(`Category ${this.categoryId}`);
69
- return super.onLoad(html);
70
- }
71
-
72
- willShow() {
73
- this.loadedAt = Date.now();
74
- }
75
-
76
- onRefresh() {
77
- console.log("ProductList refreshed");
78
- }
79
- }
80
-
81
- DOM events
82
- ----------
83
-
84
- Controller events are delegated through the document window and stored as
85
- ``sdc_<event-name>`` attributes on matching elements.
86
-
87
- Example:
88
-
89
- .. code-block:: javascript
90
-
91
- class TodoList extends AbstractSDC {
92
- constructor() {
93
- super();
94
- this.events.unshift({
95
- click: {
96
- ".add-button": "addItem",
97
- ".delete-button": "deleteItem",
98
- },
99
- submit: {
100
- "form": "saveForm",
101
- },
102
- });
103
- }
104
-
105
- addItem($element, event) {}
106
- deleteItem($element, event) {}
107
- saveForm($element, event) {}
108
- }
109
-
110
- The handler receives:
111
-
112
- - the matched jQuery element
113
- - the original browser event
114
-
115
- You can also register events at runtime with ``addEvent(event, selector,
116
- handler)``.
117
-
118
- Mixins
119
- ------
120
-
121
- Controllers can aggregate other registered controller classes as mixins.
122
-
123
- .. code-block:: javascript
124
-
125
- app.register(BaseList);
126
- app.register(Sortable);
127
- app.register(Filterable);
128
-
129
- app.register(ProductList)
130
- .addMixin(Sortable, Filterable);
131
-
132
- Mixin methods and event definitions are merged into the controller instance.
133
- Lifecycle methods on mixins are invoked through ``AbstractSDC._runLifecycle()``.
134
-
135
- Refresh, reload, and reconciliation
136
- -----------------------------------
137
-
138
- ``refresh()``
139
- Re-runs nested controller replacement and handler-bound ``<this.*>`` DOM
140
- fragments inside the controller container.
141
-
142
- ``reload()``
143
- Reloads the controller HTML from ``contentUrl`` and reconciles it into the
144
- existing DOM tree.
145
-
146
- ``reconcile($virtualNode, $realNode = null)``
147
- Diffs the virtual and real DOM trees and preserves matching elements where
148
- possible. This is used to keep elements such as form inputs stable across
149
- updates.
150
-
151
- Safe DOM helpers
152
- ----------------
153
-
154
- The runtime installs jQuery helpers:
155
-
156
- - ``$elem.safeReplace($new)``
157
- - ``$elem.safeEmpty()``
158
- - ``$elem.safeRemove()``
159
-
160
- These helpers call controller removal logic before modifying the DOM so child
161
- controllers can clean up sockets, events, and internal state.
162
-
163
- Rendering dynamic fragments with ``sdcDom`` and ``<this.*>``
164
- ------------------------------------------------------------
165
-
166
- The global ``window.sdcDom()`` helper creates DOM fragments compatible with
167
- the controller refresh pipeline.
168
-
169
- When the tag name is a function, the runtime creates a ``<this.functionName>``
170
- placeholder that is rebound during refresh.
171
-
172
- This enables patterns like:
173
-
174
- .. code-block:: javascript
175
-
176
- class Demo extends AbstractSDC {
177
- onLoad(html) {
178
- $(html).append("<this.listview></this.listview>");
179
- return super.onLoad(html);
180
- }
181
-
182
- listview() {
183
- return "<div>Dynamic content</div>";
184
- }
185
- }
186
-
187
- During ``refresh()``, the runtime resolves these placeholders by calling the
188
- matching controller method and reconciling the result into the current DOM.
189
-
190
- Backend method calls
191
- --------------------
192
-
193
- Use ``serverCall(methodName, args)`` to invoke a backend controller method.
194
-
195
- .. code-block:: javascript
196
-
197
- class InvoiceEditor extends AbstractSDC {
198
- approve() {
199
- return this.serverCall("approve", { approved: true });
200
- }
201
- }
202
-
203
- ``serverCall()`` uses:
204
-
205
- - AJAX if ``window.SERVER_CALL_VIA_WEB_SOCKET`` is falsy
206
- - WebSockets if it is truthy
207
-
208
- For ``serverCall()`` to work, ``contentUrl`` must contain an ``sdc_view/<app>/``
209
- segment so the client can infer the backend app name.
210
-
211
- Model-aware forms
212
- -----------------
213
-
214
- ``AbstractSDC`` includes a default model form submit pipeline.
215
-
216
- ``submitModelFormDistributor($form, event)``
217
- Dispatches to ``_submitModelForm()``, ``submitModelForm()``, or
218
- ``defaultSubmitModelForm()``.
219
-
220
- ``defaultSubmitModelForm($form, event)``
221
- Reads the model from form metadata, submits ``save()`` or ``create()``,
222
- clears validation errors on success, and reconciles returned error HTML on
223
- failure.
224
-
225
- Controllers and their descendants can react to the result through:
226
-
227
- - ``submit_model_form_success(result)``
228
- - ``submit_model_form_error(errorData)``
@@ -1,120 +0,0 @@
1
- Events and DOM
2
- ==============
3
-
4
- Application event bus
5
- ---------------------
6
-
7
- SimpleDomControlClient includes a small application-level event bus in addition
8
- to browser DOM events.
9
-
10
- Exports:
11
-
12
- - ``setEvent(name, functionName = name)``
13
- - ``on(name, controller)``
14
- - ``trigger(name, ...args)``
15
- - ``allOff(controller)``
16
-
17
- Usage:
18
-
19
- .. code-block:: javascript
20
-
21
- import { setEvent, on, trigger } from "sdc_client";
22
-
23
- setEvent("pushMsg", "handleMessage");
24
-
25
- class Toasts {
26
- handleMessage(title, message) {
27
- console.log(title, message);
28
- }
29
- }
30
-
31
- const toasts = new Toasts();
32
- on("pushMsg", toasts);
33
- trigger("pushMsg", "Saved", "The item was stored.");
34
-
35
- The server transport uses this event bus to emit:
36
-
37
- - ``pushMsg`` for non-error messages
38
- - ``pushErrorMsg`` for error messages
39
- - ``onNavLink`` for redirects
40
-
41
- DOM event delegation
42
- --------------------
43
-
44
- The DOM event system listens on ``window`` for standard browser events and
45
- dispatches them to controller handlers declared on matching elements.
46
-
47
- The pipeline works as follows:
48
-
49
- 1. ``initEvents()`` subscribes to standard browser events.
50
- 2. When jQuery triggers a previously unseen custom event, the runtime adds it
51
- to the watched event list automatically.
52
- 3. ``windowEventHandler()`` walks from the event target upward through the DOM.
53
- 4. For each element with a matching ``sdc_<event>`` attribute, the handler
54
- resolves the owning controller.
55
- 5. The handler name is matched either directly on the controller or through the
56
- controller event map.
57
-
58
- Declarative event attributes
59
- ----------------------------
60
-
61
- Elements can carry event attributes directly:
62
-
63
- .. code-block:: html
64
-
65
- <button sdc_click="save">Save</button>
66
-
67
- If ``save`` exists on the current controller, it will be called with:
68
-
69
- - ``$element``: the matched jQuery element
70
- - ``event``: the native event object
71
-
72
- Controller event maps
73
- ---------------------
74
-
75
- A more maintainable pattern is to define events in the controller:
76
-
77
- .. code-block:: javascript
78
-
79
- this.events.unshift({
80
- click: {
81
- ".save-button": "save",
82
- ".delete-button": "removeItem",
83
- },
84
- });
85
-
86
- At refresh time, ``setControllerEvents()`` finds the matching selectors and
87
- adds internal ``sdc_<event>`` attributes to the corresponding DOM nodes.
88
-
89
- DOM reconciliation
90
- ------------------
91
-
92
- The client contains a custom reconciliation step used by ``app.reconcile()``
93
- and controller refresh operations.
94
-
95
- Goals of reconciliation:
96
-
97
- - keep matching DOM branches when possible
98
- - update attributes and data bindings
99
- - preserve stable nodes such as input elements
100
- - remove and insert only what changed
101
-
102
- The implementation builds trees for the virtual and real DOM, computes a
103
- longest-common-branch style diff, then applies keep, delete, and insert
104
- operations in index order.
105
-
106
- This is the main reason refreshed content can preserve existing input elements
107
- instead of replacing them outright.
108
-
109
- Safe removal semantics
110
- ----------------------
111
-
112
- Always prefer the SDC-safe helpers over direct jQuery removal when a subtree may
113
- contain controllers:
114
-
115
- - ``app.safeRemove($elem)``
116
- - ``app.safeEmpty($elem)``
117
- - ``app.safeReplace($elem, $new)``
118
-
119
- These helpers call controller ``remove()`` methods first so child controllers
120
- can unregister application events, close sockets, and clean up forms.