@prabhask5/stellar-engine 1.1.6 → 1.1.8
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 +68 -25
- package/dist/actions/remoteChange.d.ts +143 -18
- package/dist/actions/remoteChange.d.ts.map +1 -1
- package/dist/actions/remoteChange.js +182 -58
- package/dist/actions/remoteChange.js.map +1 -1
- package/dist/actions/truncateTooltip.d.ts +56 -0
- package/dist/actions/truncateTooltip.d.ts.map +1 -0
- package/dist/actions/truncateTooltip.js +312 -0
- package/dist/actions/truncateTooltip.js.map +1 -0
- package/dist/auth/admin.d.ts +40 -3
- package/dist/auth/admin.d.ts.map +1 -1
- package/dist/auth/admin.js +45 -5
- package/dist/auth/admin.js.map +1 -1
- package/dist/auth/crypto.d.ts +55 -5
- package/dist/auth/crypto.d.ts.map +1 -1
- package/dist/auth/crypto.js +58 -5
- package/dist/auth/crypto.js.map +1 -1
- package/dist/auth/deviceVerification.d.ts +236 -20
- package/dist/auth/deviceVerification.d.ts.map +1 -1
- package/dist/auth/deviceVerification.js +293 -40
- package/dist/auth/deviceVerification.js.map +1 -1
- package/dist/auth/displayUtils.d.ts +98 -0
- package/dist/auth/displayUtils.d.ts.map +1 -0
- package/dist/auth/displayUtils.js +133 -0
- package/dist/auth/displayUtils.js.map +1 -0
- package/dist/auth/loginGuard.d.ts +108 -14
- package/dist/auth/loginGuard.d.ts.map +1 -1
- package/dist/auth/loginGuard.js +153 -31
- package/dist/auth/loginGuard.js.map +1 -1
- package/dist/auth/offlineCredentials.d.ts +132 -15
- package/dist/auth/offlineCredentials.d.ts.map +1 -1
- package/dist/auth/offlineCredentials.js +167 -23
- package/dist/auth/offlineCredentials.js.map +1 -1
- package/dist/auth/offlineLogin.d.ts +96 -10
- package/dist/auth/offlineLogin.d.ts.map +1 -1
- package/dist/auth/offlineLogin.js +82 -15
- package/dist/auth/offlineLogin.js.map +1 -1
- package/dist/auth/offlineSession.d.ts +83 -9
- package/dist/auth/offlineSession.d.ts.map +1 -1
- package/dist/auth/offlineSession.js +104 -13
- package/dist/auth/offlineSession.js.map +1 -1
- package/dist/auth/resolveAuthState.d.ts +70 -8
- package/dist/auth/resolveAuthState.d.ts.map +1 -1
- package/dist/auth/resolveAuthState.js +142 -46
- package/dist/auth/resolveAuthState.js.map +1 -1
- package/dist/auth/singleUser.d.ts +390 -37
- package/dist/auth/singleUser.d.ts.map +1 -1
- package/dist/auth/singleUser.js +505 -133
- package/dist/auth/singleUser.js.map +1 -1
- package/dist/bin/install-pwa.d.ts +25 -0
- package/dist/bin/install-pwa.d.ts.map +1 -0
- package/dist/bin/install-pwa.js +2197 -0
- package/dist/bin/install-pwa.js.map +1 -0
- package/dist/config.d.ts +132 -12
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +87 -9
- package/dist/config.js.map +1 -1
- package/dist/conflicts.d.ts +246 -23
- package/dist/conflicts.d.ts.map +1 -1
- package/dist/conflicts.js +495 -46
- package/dist/conflicts.js.map +1 -1
- package/dist/data.d.ts +338 -18
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +385 -34
- package/dist/data.js.map +1 -1
- package/dist/database.d.ts +72 -14
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +120 -29
- package/dist/database.js.map +1 -1
- package/dist/debug.d.ts +77 -1
- package/dist/debug.d.ts.map +1 -1
- package/dist/debug.js +88 -1
- package/dist/debug.js.map +1 -1
- package/dist/deviceId.d.ts +38 -7
- package/dist/deviceId.d.ts.map +1 -1
- package/dist/deviceId.js +68 -10
- package/dist/deviceId.js.map +1 -1
- package/dist/engine.d.ts +175 -3
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +831 -110
- package/dist/engine.js.map +1 -1
- package/dist/entries/actions.d.ts +14 -0
- package/dist/entries/actions.d.ts.map +1 -1
- package/dist/entries/actions.js +27 -1
- package/dist/entries/actions.js.map +1 -1
- package/dist/entries/auth.d.ts +16 -0
- package/dist/entries/auth.d.ts.map +1 -1
- package/dist/entries/auth.js +73 -1
- package/dist/entries/auth.js.map +1 -1
- package/dist/entries/config.d.ts +12 -0
- package/dist/entries/config.d.ts.map +1 -1
- package/dist/entries/config.js +18 -1
- package/dist/entries/config.js.map +1 -1
- package/dist/entries/kit.d.ts +21 -9
- package/dist/entries/kit.d.ts.map +1 -1
- package/dist/entries/kit.js +57 -8
- package/dist/entries/kit.js.map +1 -1
- package/dist/entries/stores.d.ts +11 -0
- package/dist/entries/stores.d.ts.map +1 -1
- package/dist/entries/stores.js +43 -2
- package/dist/entries/stores.js.map +1 -1
- package/dist/entries/types.d.ts +11 -1
- package/dist/entries/types.d.ts.map +1 -1
- package/dist/entries/types.js +10 -0
- package/dist/entries/types.js.map +1 -1
- package/dist/entries/utils.d.ts +7 -1
- package/dist/entries/utils.d.ts.map +1 -1
- package/dist/entries/utils.js +23 -2
- package/dist/entries/utils.js.map +1 -1
- package/dist/entries/vite.d.ts +20 -0
- package/dist/entries/vite.d.ts.map +1 -0
- package/dist/entries/vite.js +26 -0
- package/dist/entries/vite.js.map +1 -0
- package/dist/index.d.ts +33 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +176 -21
- package/dist/index.js.map +1 -1
- package/dist/kit/auth.d.ts +80 -0
- package/dist/kit/auth.d.ts.map +1 -0
- package/dist/kit/auth.js +72 -0
- package/dist/kit/auth.js.map +1 -0
- package/dist/kit/confirm.d.ts +111 -0
- package/dist/kit/confirm.d.ts.map +1 -0
- package/dist/kit/confirm.js +169 -0
- package/dist/kit/confirm.js.map +1 -0
- package/dist/kit/loads.d.ts +189 -0
- package/dist/kit/loads.d.ts.map +1 -0
- package/dist/kit/loads.js +205 -0
- package/dist/kit/loads.js.map +1 -0
- package/dist/kit/server.d.ts +175 -0
- package/dist/kit/server.d.ts.map +1 -0
- package/dist/kit/server.js +297 -0
- package/dist/kit/server.js.map +1 -0
- package/dist/kit/sw.d.ts +176 -0
- package/dist/kit/sw.d.ts.map +1 -0
- package/dist/kit/sw.js +320 -0
- package/dist/kit/sw.js.map +1 -0
- package/dist/queue.d.ts +274 -0
- package/dist/queue.d.ts.map +1 -1
- package/dist/queue.js +556 -38
- package/dist/queue.js.map +1 -1
- package/dist/realtime.d.ts +241 -27
- package/dist/realtime.d.ts.map +1 -1
- package/dist/realtime.js +633 -109
- package/dist/realtime.js.map +1 -1
- package/dist/runtime/runtimeConfig.d.ts +91 -16
- package/dist/runtime/runtimeConfig.d.ts.map +1 -1
- package/dist/runtime/runtimeConfig.js +146 -19
- package/dist/runtime/runtimeConfig.js.map +1 -1
- package/dist/stores/authState.d.ts +150 -11
- package/dist/stores/authState.d.ts.map +1 -1
- package/dist/stores/authState.js +169 -17
- package/dist/stores/authState.js.map +1 -1
- package/dist/stores/network.d.ts +39 -0
- package/dist/stores/network.d.ts.map +1 -1
- package/dist/stores/network.js +169 -16
- package/dist/stores/network.js.map +1 -1
- package/dist/stores/remoteChanges.d.ts +327 -52
- package/dist/stores/remoteChanges.d.ts.map +1 -1
- package/dist/stores/remoteChanges.js +337 -75
- package/dist/stores/remoteChanges.js.map +1 -1
- package/dist/stores/sync.d.ts +130 -0
- package/dist/stores/sync.d.ts.map +1 -1
- package/dist/stores/sync.js +167 -7
- package/dist/stores/sync.js.map +1 -1
- package/dist/supabase/auth.d.ts +326 -19
- package/dist/supabase/auth.d.ts.map +1 -1
- package/dist/supabase/auth.js +374 -26
- package/dist/supabase/auth.js.map +1 -1
- package/dist/supabase/client.d.ts +79 -6
- package/dist/supabase/client.d.ts.map +1 -1
- package/dist/supabase/client.js +158 -15
- package/dist/supabase/client.js.map +1 -1
- package/dist/supabase/validate.d.ts +101 -7
- package/dist/supabase/validate.d.ts.map +1 -1
- package/dist/supabase/validate.js +117 -8
- package/dist/supabase/validate.js.map +1 -1
- package/dist/sw/build/vite-plugin.d.ts +74 -0
- package/dist/sw/build/vite-plugin.d.ts.map +1 -0
- package/dist/sw/build/vite-plugin.js +183 -0
- package/dist/sw/build/vite-plugin.js.map +1 -0
- package/dist/sw/sw.js +669 -0
- package/dist/types.d.ts +150 -45
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +12 -10
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +55 -13
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +83 -22
- package/dist/utils.js.map +1 -1
- package/package.json +20 -22
- package/src/components/DeferredChangesBanner.svelte +477 -0
- package/src/components/SyncStatus.svelte +1732 -0
- package/dist/crdt/awareness.d.ts +0 -54
- package/dist/crdt/awareness.d.ts.map +0 -1
- package/dist/crdt/awareness.js +0 -219
- package/dist/crdt/awareness.js.map +0 -1
- package/dist/crdt/doc.d.ts +0 -56
- package/dist/crdt/doc.d.ts.map +0 -1
- package/dist/crdt/doc.js +0 -130
- package/dist/crdt/doc.js.map +0 -1
- package/dist/crdt/index.d.ts +0 -15
- package/dist/crdt/index.d.ts.map +0 -1
- package/dist/crdt/index.js +0 -20
- package/dist/crdt/index.js.map +0 -1
- package/dist/crdt/offline.d.ts +0 -91
- package/dist/crdt/offline.d.ts.map +0 -1
- package/dist/crdt/offline.js +0 -353
- package/dist/crdt/offline.js.map +0 -1
- package/dist/crdt/sync.d.ts +0 -58
- package/dist/crdt/sync.d.ts.map +0 -1
- package/dist/crdt/sync.js +0 -399
- package/dist/crdt/sync.js.map +0 -1
- package/dist/crdt/types.d.ts +0 -62
- package/dist/crdt/types.d.ts.map +0 -1
- package/dist/crdt/types.js +0 -7
- package/dist/crdt/types.js.map +0 -1
- package/dist/email/sendEmail.d.ts +0 -31
- package/dist/email/sendEmail.d.ts.map +0 -1
- package/dist/email/sendEmail.js +0 -39
- package/dist/email/sendEmail.js.map +0 -1
- package/dist/email/validateSmtp.d.ts +0 -18
- package/dist/email/validateSmtp.d.ts.map +0 -1
- package/dist/email/validateSmtp.js +0 -33
- package/dist/email/validateSmtp.js.map +0 -1
- package/dist/entries/crdt.d.ts +0 -3
- package/dist/entries/crdt.d.ts.map +0 -1
- package/dist/entries/crdt.js +0 -13
- package/dist/entries/crdt.js.map +0 -1
- package/dist/entries/email.d.ts +0 -4
- package/dist/entries/email.d.ts.map +0 -1
- package/dist/entries/email.js +0 -4
- package/dist/entries/email.js.map +0 -1
- package/dist/kit/authPresets.d.ts +0 -28
- package/dist/kit/authPresets.d.ts.map +0 -1
- package/dist/kit/authPresets.js +0 -23
- package/dist/kit/authPresets.js.map +0 -1
- package/dist/kit/configEndpoint.d.ts +0 -18
- package/dist/kit/configEndpoint.d.ts.map +0 -1
- package/dist/kit/configEndpoint.js +0 -27
- package/dist/kit/configEndpoint.js.map +0 -1
- package/dist/kit/deployEndpoint.d.ts +0 -22
- package/dist/kit/deployEndpoint.d.ts.map +0 -1
- package/dist/kit/deployEndpoint.js +0 -79
- package/dist/kit/deployEndpoint.js.map +0 -1
- package/dist/kit/layoutLoad.d.ts +0 -23
- package/dist/kit/layoutLoad.d.ts.map +0 -1
- package/dist/kit/layoutLoad.js +0 -41
- package/dist/kit/layoutLoad.js.map +0 -1
- package/dist/kit/protectedLoad.d.ts +0 -16
- package/dist/kit/protectedLoad.d.ts.map +0 -1
- package/dist/kit/protectedLoad.js +0 -28
- package/dist/kit/protectedLoad.js.map +0 -1
- package/dist/kit/setupLoad.d.ts +0 -11
- package/dist/kit/setupLoad.d.ts.map +0 -1
- package/dist/kit/setupLoad.js +0 -28
- package/dist/kit/setupLoad.js.map +0 -1
- package/dist/kit/validateEndpoint.d.ts +0 -9
- package/dist/kit/validateEndpoint.d.ts.map +0 -1
- package/dist/kit/validateEndpoint.js +0 -25
- package/dist/kit/validateEndpoint.js.map +0 -1
- package/dist/kit/vercelApi.d.ts +0 -6
- package/dist/kit/vercelApi.d.ts.map +0 -1
- package/dist/kit/vercelApi.js +0 -48
- package/dist/kit/vercelApi.js.map +0 -1
|
@@ -1,30 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Remote Change Animation Action
|
|
2
|
+
* @fileoverview Remote Change Animation Action
|
|
3
3
|
*
|
|
4
4
|
* A Svelte action that automatically adds remote change animations to elements.
|
|
5
|
-
* Use this on list items, cards, or any element that can be updated remotely
|
|
5
|
+
* Use this on list items, cards, or any element that can be updated remotely
|
|
6
|
+
* (e.g., via Supabase Realtime subscriptions).
|
|
6
7
|
*
|
|
7
8
|
* The action detects the ACTION TYPE from the remote change and applies
|
|
8
|
-
* the appropriate animation:
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
9
|
+
* the appropriate CSS animation class:
|
|
10
|
+
* - `'create'` --> `item-created` (slide in with burst)
|
|
11
|
+
* - `'delete'` --> `item-deleting` (slide out with fade)
|
|
12
|
+
* - `'toggle'` --> `item-toggled` (+ checkbox-animating + completion-ripple)
|
|
13
|
+
* - `'increment'` --> `counter-increment` (bump up)
|
|
14
|
+
* - `'decrement'` --> `counter-decrement` (bump down)
|
|
15
|
+
* - `'reorder'` --> `item-reordering` (slide to new position)
|
|
16
|
+
* - `'rename'` --> `text-changed` (highlight flash)
|
|
17
|
+
* - `'update'` --> `item-changed` (default highlight)
|
|
17
18
|
*
|
|
18
|
-
*
|
|
19
|
+
* @example
|
|
19
20
|
* ```svelte
|
|
20
21
|
* <div use:remoteChangeAnimation={{ entityId: item.id, entityType: 'goals' }}>
|
|
21
22
|
* ...
|
|
22
23
|
* </div>
|
|
23
24
|
* ```
|
|
25
|
+
*
|
|
26
|
+
* @see {@link remoteChangeAnimation} for the main Svelte action
|
|
27
|
+
* @see {@link trackEditing} for deferred-change tracking on forms
|
|
28
|
+
* @see {@link triggerLocalAnimation} for programmatic local animations
|
|
24
29
|
*/
|
|
25
30
|
import { remoteChangesStore, createRecentChangeIndicator, createPendingDeleteIndicator } from '../stores/remoteChanges';
|
|
31
|
+
// =============================================================================
|
|
32
|
+
// ACTION-TO-CSS ANIMATION MAPPING
|
|
33
|
+
// =============================================================================
|
|
26
34
|
/**
|
|
27
|
-
*
|
|
35
|
+
* Maps each {@link RemoteActionType} to the CSS class name that triggers
|
|
36
|
+
* the corresponding animation. The consuming app must define these CSS
|
|
37
|
+
* classes (keyframes + durations) in its stylesheet.
|
|
28
38
|
*/
|
|
29
39
|
const ACTION_ANIMATION_MAP = {
|
|
30
40
|
create: 'item-created',
|
|
@@ -37,7 +47,9 @@ const ACTION_ANIMATION_MAP = {
|
|
|
37
47
|
update: 'item-changed'
|
|
38
48
|
};
|
|
39
49
|
/**
|
|
40
|
-
*
|
|
50
|
+
* Maps each {@link RemoteActionType} to its animation duration in
|
|
51
|
+
* milliseconds. Used for fallback cleanup timers in case the
|
|
52
|
+
* `animationend` DOM event never fires (e.g., display:none elements).
|
|
41
53
|
*/
|
|
42
54
|
const ACTION_DURATION_MAP = {
|
|
43
55
|
create: 600,
|
|
@@ -49,49 +61,95 @@ const ACTION_DURATION_MAP = {
|
|
|
49
61
|
rename: 700,
|
|
50
62
|
update: 1600
|
|
51
63
|
};
|
|
52
|
-
//
|
|
64
|
+
// =============================================================================
|
|
65
|
+
// ANIMATION OVERLAP PREVENTION
|
|
66
|
+
// =============================================================================
|
|
67
|
+
/**
|
|
68
|
+
* Tracks elements that currently have an active animation. Prevents
|
|
69
|
+
* overlapping animations on the same element which would cause visual
|
|
70
|
+
* glitches. Uses `WeakSet` so entries are automatically garbage-collected
|
|
71
|
+
* when the element is removed from the DOM.
|
|
72
|
+
*/
|
|
53
73
|
const animatingElements = new WeakSet();
|
|
74
|
+
// =============================================================================
|
|
75
|
+
// SVELTE ACTION: remoteChangeAnimation
|
|
76
|
+
// =============================================================================
|
|
77
|
+
/**
|
|
78
|
+
* Svelte action that watches for remote changes on a specific entity and
|
|
79
|
+
* applies the appropriate CSS animation class to the host element.
|
|
80
|
+
*
|
|
81
|
+
* **Lifecycle:**
|
|
82
|
+
* 1. On mount, checks for a recent change that may have arrived before
|
|
83
|
+
* the element was rendered (important for CREATE animations on new items).
|
|
84
|
+
* 2. Subscribes to the `remoteChangesStore` for future changes.
|
|
85
|
+
* 3. Subscribes to a pending-delete indicator for delete animations.
|
|
86
|
+
* 4. On update, re-subscribes if the entity identity changes.
|
|
87
|
+
* 5. On destroy, unsubscribes and cleans up CSS classes.
|
|
88
|
+
*
|
|
89
|
+
* @param node - The DOM element to animate.
|
|
90
|
+
* @param options - Configuration specifying which entity to watch.
|
|
91
|
+
* @returns A Svelte action lifecycle object with `update` and `destroy` methods.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```svelte
|
|
95
|
+
* <div use:remoteChangeAnimation={{ entityId: item.id, entityType: 'goals' }}>
|
|
96
|
+
* {item.name}
|
|
97
|
+
* </div>
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
54
100
|
export function remoteChangeAnimation(node, options) {
|
|
55
101
|
let { entityId, entityType, fields, animationClass, onAction } = options;
|
|
56
|
-
|
|
102
|
+
/* Add base class for styling hooks (e.g., transition defaults) */
|
|
57
103
|
node.classList.add('syncable-item');
|
|
58
|
-
//
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
// ANIMATION APPLICATION LOGIC
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
/**
|
|
108
|
+
* Apply the appropriate CSS animation to the node based on the change's
|
|
109
|
+
* action type and affected fields.
|
|
110
|
+
*
|
|
111
|
+
* Handles special cases for toggle (checkbox + ripple), increment/decrement
|
|
112
|
+
* (counter sub-element), and delete (no class removal — element will be
|
|
113
|
+
* removed from DOM by the parent component).
|
|
114
|
+
*
|
|
115
|
+
* @param change - The remote change descriptor with `actionType` and `fields`.
|
|
116
|
+
*/
|
|
59
117
|
function applyAnimation(change) {
|
|
60
|
-
|
|
118
|
+
/* If specific fields are configured, only animate if at least one matches */
|
|
61
119
|
if (fields && fields.length > 0) {
|
|
62
|
-
const fieldsList = fields;
|
|
120
|
+
const fieldsList = fields; /* Capture for closure safety */
|
|
63
121
|
const hasRelevantChange = change.fields.some((f) => f === '*' || fieldsList.includes(f));
|
|
64
122
|
if (!hasRelevantChange)
|
|
65
123
|
return;
|
|
66
124
|
}
|
|
67
|
-
|
|
125
|
+
/* Prevent overlapping animations on the same element */
|
|
68
126
|
if (animatingElements.has(node))
|
|
69
127
|
return;
|
|
70
128
|
animatingElements.add(node);
|
|
71
|
-
|
|
129
|
+
/* Determine animation class based on action type */
|
|
72
130
|
const actionType = change.actionType;
|
|
73
131
|
const cssClass = animationClass || ACTION_ANIMATION_MAP[actionType] || 'item-changed';
|
|
74
132
|
const duration = ACTION_DURATION_MAP[actionType] || 1600;
|
|
75
|
-
|
|
133
|
+
/* Call action callback if provided (for component-specific handling) */
|
|
76
134
|
if (onAction) {
|
|
77
135
|
onAction(actionType, change.fields);
|
|
78
136
|
}
|
|
79
|
-
|
|
137
|
+
/* Apply animation class */
|
|
80
138
|
node.classList.add(cssClass);
|
|
81
|
-
|
|
139
|
+
/* For toggle actions, also add checkbox animation to child checkbox elements */
|
|
82
140
|
if (actionType === 'toggle') {
|
|
83
141
|
const checkbox = node.querySelector('.checkbox, [class*="checkbox"]');
|
|
84
142
|
if (checkbox) {
|
|
85
143
|
checkbox.classList.add('checkbox-animating');
|
|
86
144
|
setTimeout(() => checkbox.classList.remove('checkbox-animating'), 500);
|
|
87
145
|
}
|
|
88
|
-
|
|
146
|
+
/* Add completion ripple effect — a temporary <span> that auto-removes */
|
|
89
147
|
const ripple = document.createElement('span');
|
|
90
148
|
ripple.className = 'completion-ripple';
|
|
91
149
|
node.appendChild(ripple);
|
|
92
150
|
setTimeout(() => ripple.remove(), 700);
|
|
93
151
|
}
|
|
94
|
-
|
|
152
|
+
/* For increment/decrement, animate the counter sub-element specifically */
|
|
95
153
|
if (actionType === 'increment' || actionType === 'decrement') {
|
|
96
154
|
const counter = node.querySelector('[class*="value"], [class*="counter"], [class*="current"]');
|
|
97
155
|
if (counter) {
|
|
@@ -99,60 +157,78 @@ export function remoteChangeAnimation(node, options) {
|
|
|
99
157
|
setTimeout(() => counter.classList.remove(cssClass), duration);
|
|
100
158
|
}
|
|
101
159
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
160
|
+
/* For delete animations, don't remove the class — the element will be
|
|
161
|
+
* removed from DOM after the animation. Removing it early causes the item
|
|
162
|
+
* to briefly reappear between animation end and DOM removal. */
|
|
105
163
|
if (actionType === 'delete')
|
|
106
164
|
return;
|
|
107
|
-
|
|
165
|
+
/* Remove class after animation completes */
|
|
108
166
|
const handleAnimationEnd = () => {
|
|
109
167
|
node.classList.remove(cssClass);
|
|
110
168
|
animatingElements.delete(node);
|
|
111
169
|
node.removeEventListener('animationend', handleAnimationEnd);
|
|
112
170
|
};
|
|
113
171
|
node.addEventListener('animationend', handleAnimationEnd);
|
|
114
|
-
|
|
172
|
+
/* Fallback removal in case animationend doesn't fire
|
|
173
|
+
* (e.g., element is display:none or animation is interrupted) */
|
|
115
174
|
setTimeout(() => {
|
|
116
175
|
node.classList.remove(cssClass);
|
|
117
176
|
animatingElements.delete(node);
|
|
118
177
|
}, duration + 100);
|
|
119
178
|
}
|
|
120
|
-
//
|
|
121
|
-
//
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
// INITIAL CHECK (HANDLES CREATE-ON-MOUNT SCENARIO)
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
/* Check for a recent change immediately on mount. This handles the case
|
|
183
|
+
* where the element mounts after a remote INSERT — the store already has
|
|
184
|
+
* the change recorded, and we need to animate the newly-rendered item. */
|
|
122
185
|
const initialChange = remoteChangesStore.getRecentChange(entityId, entityType);
|
|
123
186
|
if (initialChange) {
|
|
124
|
-
|
|
187
|
+
/* Use requestAnimationFrame to ensure DOM is fully ready */
|
|
125
188
|
requestAnimationFrame(() => {
|
|
126
189
|
applyAnimation(initialChange);
|
|
127
190
|
});
|
|
128
191
|
}
|
|
129
|
-
//
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
// STORE SUBSCRIPTIONS
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
/* Create derived stores to watch for future changes and pending deletes */
|
|
130
196
|
let changeIndicator = createRecentChangeIndicator(entityId, entityType);
|
|
131
197
|
let deleteIndicator = createPendingDeleteIndicator(entityId, entityType);
|
|
132
|
-
|
|
198
|
+
/* Track the current unsubscribe functions */
|
|
133
199
|
let unsubscribeChange = changeIndicator.subscribe((change) => {
|
|
134
|
-
|
|
200
|
+
/* Skip if no change or if this is the same change we already animated on mount */
|
|
135
201
|
if (!change)
|
|
136
202
|
return;
|
|
137
203
|
if (initialChange && change.timestamp === initialChange.timestamp)
|
|
138
204
|
return;
|
|
139
205
|
applyAnimation(change);
|
|
140
206
|
});
|
|
141
|
-
|
|
207
|
+
/* Watch for pending deletes to apply delete animation */
|
|
142
208
|
let unsubscribeDelete = deleteIndicator.subscribe((isPendingDelete) => {
|
|
143
209
|
if (isPendingDelete) {
|
|
144
|
-
|
|
210
|
+
/* Apply delete animation immediately */
|
|
145
211
|
const deleteClass = ACTION_ANIMATION_MAP['delete'];
|
|
146
212
|
node.classList.add(deleteClass);
|
|
147
|
-
|
|
213
|
+
/* Call action callback if provided */
|
|
148
214
|
if (onAction) {
|
|
149
215
|
onAction('delete', ['*']);
|
|
150
216
|
}
|
|
151
217
|
}
|
|
152
218
|
});
|
|
219
|
+
// ---------------------------------------------------------------------------
|
|
220
|
+
// SVELTE ACTION LIFECYCLE
|
|
221
|
+
// ---------------------------------------------------------------------------
|
|
153
222
|
return {
|
|
223
|
+
/**
|
|
224
|
+
* Called when the action's options change. If the entity identity
|
|
225
|
+
* (`entityId` or `entityType`) has changed, tears down old subscriptions
|
|
226
|
+
* and creates new ones for the updated entity.
|
|
227
|
+
*
|
|
228
|
+
* @param newOptions - The updated {@link RemoteChangeOptions}.
|
|
229
|
+
*/
|
|
154
230
|
update(newOptions) {
|
|
155
|
-
|
|
231
|
+
/* If entity changed, re-subscribe with new entity */
|
|
156
232
|
if (newOptions.entityId !== entityId || newOptions.entityType !== entityType) {
|
|
157
233
|
unsubscribeChange();
|
|
158
234
|
unsubscribeDelete();
|
|
@@ -179,6 +255,10 @@ export function remoteChangeAnimation(node, options) {
|
|
|
179
255
|
});
|
|
180
256
|
}
|
|
181
257
|
},
|
|
258
|
+
/**
|
|
259
|
+
* Cleanup handler — unsubscribes from all stores, removes the base
|
|
260
|
+
* CSS class, and clears the element from the animation tracking set.
|
|
261
|
+
*/
|
|
182
262
|
destroy() {
|
|
183
263
|
unsubscribeChange();
|
|
184
264
|
unsubscribeDelete();
|
|
@@ -187,11 +267,31 @@ export function remoteChangeAnimation(node, options) {
|
|
|
187
267
|
}
|
|
188
268
|
};
|
|
189
269
|
}
|
|
270
|
+
/**
|
|
271
|
+
* Svelte action that marks an entity as "being edited" in the remote changes
|
|
272
|
+
* store. While editing, incoming remote changes for the same entity are
|
|
273
|
+
* deferred instead of applied immediately.
|
|
274
|
+
*
|
|
275
|
+
* **Lifecycle:**
|
|
276
|
+
* 1. On mount, calls `remoteChangesStore.startEditing()` to begin deferral.
|
|
277
|
+
* 2. Periodically checks for deferred changes and toggles a CSS class
|
|
278
|
+
* (`has-deferred-changes`) on the node for visual indication.
|
|
279
|
+
* 3. On update, re-registers if the entity identity changes.
|
|
280
|
+
* 4. On destroy, calls `remoteChangesStore.stopEditing()` and invokes
|
|
281
|
+
* `onDeferredChanges` if any changes were deferred.
|
|
282
|
+
*
|
|
283
|
+
* @param node - The form DOM element.
|
|
284
|
+
* @param options - Configuration specifying which entity is being edited.
|
|
285
|
+
* @returns A Svelte action lifecycle object with `update` and `destroy` methods.
|
|
286
|
+
*/
|
|
190
287
|
export function trackEditing(node, options) {
|
|
191
288
|
const { entityId, entityType, formType, fields, onDeferredChanges } = options;
|
|
192
|
-
|
|
289
|
+
/* Start tracking when the element mounts */
|
|
193
290
|
remoteChangesStore.startEditing(entityId, entityType, formType, fields);
|
|
194
|
-
|
|
291
|
+
/**
|
|
292
|
+
* Update the `has-deferred-changes` CSS class based on whether
|
|
293
|
+
* remote changes have been deferred for this entity.
|
|
294
|
+
*/
|
|
195
295
|
const updateDeferredIndicator = () => {
|
|
196
296
|
const hasDeferred = remoteChangesStore.hasDeferredChanges(entityId, entityType);
|
|
197
297
|
if (hasDeferred) {
|
|
@@ -201,34 +301,58 @@ export function trackEditing(node, options) {
|
|
|
201
301
|
node.classList.remove('has-deferred-changes');
|
|
202
302
|
}
|
|
203
303
|
};
|
|
204
|
-
|
|
304
|
+
/* Check periodically for deferred changes (1-second polling interval) */
|
|
205
305
|
const interval = setInterval(updateDeferredIndicator, 1000);
|
|
206
306
|
updateDeferredIndicator();
|
|
207
307
|
return {
|
|
308
|
+
/**
|
|
309
|
+
* Called when the action's options change. If the entity identity
|
|
310
|
+
* changes, stops tracking the old entity and starts tracking the new one.
|
|
311
|
+
*
|
|
312
|
+
* @param newOptions - The updated {@link TrackEditingOptions}.
|
|
313
|
+
*/
|
|
208
314
|
update(newOptions) {
|
|
209
|
-
|
|
315
|
+
/* If entity changed, stop old tracking and start new */
|
|
210
316
|
if (newOptions.entityId !== entityId || newOptions.entityType !== entityType) {
|
|
211
317
|
remoteChangesStore.stopEditing(entityId, entityType);
|
|
212
318
|
remoteChangesStore.startEditing(newOptions.entityId, newOptions.entityType, newOptions.formType, newOptions.fields);
|
|
213
319
|
}
|
|
214
320
|
},
|
|
321
|
+
/**
|
|
322
|
+
* Cleanup handler — stops the polling interval, removes CSS classes,
|
|
323
|
+
* stops editing in the store, and notifies the callback of any
|
|
324
|
+
* deferred changes that accumulated during the editing session.
|
|
325
|
+
*/
|
|
215
326
|
destroy() {
|
|
216
327
|
clearInterval(interval);
|
|
217
328
|
node.classList.remove('has-deferred-changes');
|
|
218
|
-
|
|
329
|
+
/* Stop tracking and get any deferred changes */
|
|
219
330
|
const deferredChanges = remoteChangesStore.stopEditing(entityId, entityType);
|
|
220
|
-
|
|
331
|
+
/* Notify callback if there are deferred changes */
|
|
221
332
|
if (deferredChanges.length > 0 && onDeferredChanges) {
|
|
222
333
|
onDeferredChanges(deferredChanges);
|
|
223
334
|
}
|
|
224
335
|
}
|
|
225
336
|
};
|
|
226
337
|
}
|
|
338
|
+
// =============================================================================
|
|
339
|
+
// PROGRAMMATIC LOCAL ANIMATION TRIGGER
|
|
340
|
+
// =============================================================================
|
|
227
341
|
/**
|
|
228
342
|
* Trigger a local action animation on an element.
|
|
229
|
-
* Use this to make local actions animate the same way as remote actions.
|
|
230
343
|
*
|
|
231
|
-
*
|
|
344
|
+
* Use this to make local user actions (e.g., tapping a checkbox, incrementing
|
|
345
|
+
* a counter) animate with the same visual treatment as remote changes, giving
|
|
346
|
+
* the UI a consistent feel.
|
|
347
|
+
*
|
|
348
|
+
* For `increment` and `decrement` actions, rapid repeated invocations will
|
|
349
|
+
* restart the animation instead of being blocked — this allows the counter
|
|
350
|
+
* to visually "bump" on each tap.
|
|
351
|
+
*
|
|
352
|
+
* @param element - The DOM element to animate (or `null`, in which case this is a no-op).
|
|
353
|
+
* @param actionType - The type of animation to apply.
|
|
354
|
+
*
|
|
355
|
+
* @example
|
|
232
356
|
* ```svelte
|
|
233
357
|
* <script>
|
|
234
358
|
* import { triggerLocalAnimation } from '@prabhask5/stellar-engine';
|
|
@@ -247,36 +371,36 @@ export function triggerLocalAnimation(element, actionType) {
|
|
|
247
371
|
return;
|
|
248
372
|
const cssClass = ACTION_ANIMATION_MAP[actionType] || 'item-changed';
|
|
249
373
|
const duration = ACTION_DURATION_MAP[actionType] || 1600;
|
|
250
|
-
|
|
374
|
+
/* For increment/decrement, restart animation on rapid taps instead of blocking */
|
|
251
375
|
if (actionType === 'increment' || actionType === 'decrement') {
|
|
252
376
|
if (animatingElements.has(element)) {
|
|
253
|
-
|
|
377
|
+
/* Force restart: remove class, trigger reflow via offsetWidth read, re-add */
|
|
254
378
|
element.classList.remove(cssClass);
|
|
255
379
|
void element.offsetWidth;
|
|
256
380
|
}
|
|
257
381
|
}
|
|
258
382
|
else {
|
|
259
|
-
|
|
383
|
+
/* Prevent overlapping animations for other types */
|
|
260
384
|
if (animatingElements.has(element))
|
|
261
385
|
return;
|
|
262
386
|
}
|
|
263
387
|
animatingElements.add(element);
|
|
264
|
-
|
|
388
|
+
/* Apply animation class */
|
|
265
389
|
element.classList.add(cssClass);
|
|
266
|
-
|
|
390
|
+
/* For toggle actions, also animate checkbox elements */
|
|
267
391
|
if (actionType === 'toggle') {
|
|
268
392
|
const checkbox = element.querySelector('.checkbox, [class*="checkbox"]');
|
|
269
393
|
if (checkbox) {
|
|
270
394
|
checkbox.classList.add('checkbox-animating');
|
|
271
395
|
setTimeout(() => checkbox.classList.remove('checkbox-animating'), 500);
|
|
272
396
|
}
|
|
273
|
-
|
|
397
|
+
/* Add completion ripple effect */
|
|
274
398
|
const ripple = document.createElement('span');
|
|
275
399
|
ripple.className = 'completion-ripple';
|
|
276
400
|
element.appendChild(ripple);
|
|
277
401
|
setTimeout(() => ripple.remove(), 700);
|
|
278
402
|
}
|
|
279
|
-
|
|
403
|
+
/* For increment/decrement, animate the counter sub-element specifically */
|
|
280
404
|
if (actionType === 'increment' || actionType === 'decrement') {
|
|
281
405
|
const counter = element.querySelector('[class*="value"], [class*="counter"], [class*="current"]');
|
|
282
406
|
if (counter) {
|
|
@@ -284,14 +408,14 @@ export function triggerLocalAnimation(element, actionType) {
|
|
|
284
408
|
setTimeout(() => counter.classList.remove(cssClass), duration);
|
|
285
409
|
}
|
|
286
410
|
}
|
|
287
|
-
|
|
411
|
+
/* Remove class after animation completes */
|
|
288
412
|
const handleAnimationEnd = () => {
|
|
289
413
|
element.classList.remove(cssClass);
|
|
290
414
|
animatingElements.delete(element);
|
|
291
415
|
element.removeEventListener('animationend', handleAnimationEnd);
|
|
292
416
|
};
|
|
293
417
|
element.addEventListener('animationend', handleAnimationEnd);
|
|
294
|
-
|
|
418
|
+
/* Fallback removal in case animationend doesn't fire */
|
|
295
419
|
setTimeout(() => {
|
|
296
420
|
element.classList.remove(cssClass);
|
|
297
421
|
animatingElements.delete(element);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteChange.js","sourceRoot":"","sources":["../../src/actions/remoteChange.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"remoteChange.js","sourceRoot":"","sources":["../../src/actions/remoteChange.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Svelte action for truncated-text tooltips.
|
|
3
|
+
*
|
|
4
|
+
* Provides a `use:truncateTooltip` directive that enforces CSS text-overflow
|
|
5
|
+
* ellipsis on the target element and shows a floating tooltip with the
|
|
6
|
+
* **full** text whenever the content is visually truncated.
|
|
7
|
+
*
|
|
8
|
+
* **Behaviour by device type:**
|
|
9
|
+
* - **Desktop** — tooltip appears on `mouseenter`, hides on `mouseleave`.
|
|
10
|
+
* Only shown when `scrollWidth > clientWidth` (text is actually clipped).
|
|
11
|
+
* - **Mobile** — tooltip appears on `touchstart` (tap), dismisses on
|
|
12
|
+
* tap-outside or after a 3-second auto-dismiss timeout.
|
|
13
|
+
*
|
|
14
|
+
* A **singleton** tooltip `<div>` is lazily appended to `document.body` and
|
|
15
|
+
* reused across all instances of the action to avoid DOM bloat.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```svelte
|
|
19
|
+
* <span class="my-text" use:truncateTooltip>{longText}</span>
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @see {@link truncateTooltip} for the Svelte action export
|
|
23
|
+
* @see {@link showTooltip} for the display logic
|
|
24
|
+
* @see {@link positionTooltip} for the positioning algorithm
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* Svelte action that applies truncation-aware tooltips to an element.
|
|
28
|
+
*
|
|
29
|
+
* **On mount the action:**
|
|
30
|
+
* 1. Forces CSS `overflow: hidden`, `text-overflow: ellipsis`, and
|
|
31
|
+
* `white-space: nowrap` on the node to guarantee ellipsis rendering.
|
|
32
|
+
* 2. Registers `mouseenter` / `mouseleave` handlers for desktop hover.
|
|
33
|
+
* 3. Registers `touchstart` handlers for mobile tap-to-show behaviour.
|
|
34
|
+
* 4. Registers a document-level `touchstart` listener for tap-outside
|
|
35
|
+
* dismissal on mobile.
|
|
36
|
+
*
|
|
37
|
+
* The returned `destroy` callback cleans up all listeners and hides the
|
|
38
|
+
* tooltip if the destroyed node was its current owner.
|
|
39
|
+
*
|
|
40
|
+
* @param node - The DOM element to enhance with truncation tooltips.
|
|
41
|
+
* @returns A Svelte action lifecycle object with a `destroy` method.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```svelte
|
|
45
|
+
* <span class="my-text" use:truncateTooltip>{longText}</span>
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare function truncateTooltip(node: HTMLElement): {
|
|
49
|
+
/**
|
|
50
|
+
* Cleanup handler — removes all event listeners and hides the tooltip
|
|
51
|
+
* if this node was the active owner. Prevents memory leaks from
|
|
52
|
+
* orphaned document-level listeners.
|
|
53
|
+
*/
|
|
54
|
+
destroy(): void;
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=truncateTooltip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"truncateTooltip.d.ts","sourceRoot":"","sources":["../../src/actions/truncateTooltip.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AA4LH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW;IA2F7C;;;;OAIG;;EAaN"}
|