@agnos-ui/core-bootstrap 0.6.0-next.2 → 0.7.0-next.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.
@@ -0,0 +1,637 @@
1
+ import { createTransition } from "@agnos-ui/core/services/transitions/baseTransitions";
2
+ import { writablesForProps, stateStores } from "@agnos-ui/core/utils/stores";
3
+ import { mergeDirectives, createAttributesDirective } from "@agnos-ui/core/utils/directive";
4
+ import { typeBoolean, typeFunction, typeString } from "@agnos-ui/core/utils/writables";
5
+ import { a as collapseHorizontalTransition, c as collapseVerticalTransition } from "./collapse-CVjUhnIz.js";
6
+ const equal = (a, b) => Object.is(a, b) && (!a || typeof a !== "object") && typeof a !== "function";
7
+ const subscribersQueue = [];
8
+ let willProcessQueue = false;
9
+ const batch = (fn) => {
10
+ const needsProcessQueue = !willProcessQueue;
11
+ willProcessQueue = true;
12
+ let success = true;
13
+ let res;
14
+ let error;
15
+ try {
16
+ res = fn();
17
+ } finally {
18
+ if (needsProcessQueue) {
19
+ while (subscribersQueue.length > 0) {
20
+ const consumer = subscribersQueue.shift();
21
+ try {
22
+ consumer.notify();
23
+ } catch (e) {
24
+ if (success) {
25
+ success = false;
26
+ error = e;
27
+ }
28
+ }
29
+ }
30
+ willProcessQueue = false;
31
+ }
32
+ }
33
+ if (success) {
34
+ return res;
35
+ }
36
+ throw error;
37
+ };
38
+ const updateLinkProducerValue = (link) => {
39
+ try {
40
+ link.skipMarkDirty = true;
41
+ link.producer.updateValue();
42
+ if (link.producer.flags & 16) {
43
+ throw new Error("assert failed: store still dirty after updating it");
44
+ }
45
+ } finally {
46
+ link.skipMarkDirty = false;
47
+ }
48
+ };
49
+ const noop = () => {
50
+ };
51
+ const bind = (object, fnName) => {
52
+ const fn = object ? object[fnName] : null;
53
+ return typeof fn === "function" ? fn.bind(object) : noop;
54
+ };
55
+ const noopSubscriber = {
56
+ next: noop,
57
+ pause: noop,
58
+ resume: noop
59
+ };
60
+ const toSubscriberObject = (subscriber) => ({
61
+ next: typeof subscriber === "function" ? subscriber.bind(null) : bind(subscriber, "next"),
62
+ pause: bind(subscriber, "pause"),
63
+ resume: bind(subscriber, "resume")
64
+ });
65
+ class SubscribeConsumer {
66
+ constructor(producer, subscriber) {
67
+ this.dirtyCount = 1;
68
+ this.subscriber = toSubscriberObject(subscriber);
69
+ this.link = producer.registerConsumer(producer.newLink(this));
70
+ this.notify(true);
71
+ }
72
+ unsubscribe() {
73
+ if (this.subscriber !== noopSubscriber) {
74
+ this.subscriber = noopSubscriber;
75
+ this.link.producer.unregisterConsumer(this.link);
76
+ }
77
+ }
78
+ markDirty() {
79
+ this.dirtyCount++;
80
+ subscribersQueue.push(this);
81
+ if (this.dirtyCount === 1) {
82
+ this.subscriber.pause();
83
+ }
84
+ }
85
+ notify(first = false) {
86
+ this.dirtyCount--;
87
+ if (this.dirtyCount === 0 && this.subscriber !== noopSubscriber) {
88
+ const link = this.link;
89
+ const producer = link.producer;
90
+ updateLinkProducerValue(link);
91
+ if (producer.isLinkUpToDate(link) && !first) {
92
+ this.subscriber.resume();
93
+ } else {
94
+ const value = producer.updateLink(link);
95
+ this.subscriber.next(value);
96
+ }
97
+ }
98
+ }
99
+ }
100
+ let activeConsumer = null;
101
+ const setActiveConsumer = (consumer) => {
102
+ const prevConsumer = activeConsumer;
103
+ activeConsumer = consumer;
104
+ return prevConsumer;
105
+ };
106
+ const untrack = (fn) => {
107
+ let output;
108
+ const prevActiveConsumer = setActiveConsumer(null);
109
+ try {
110
+ output = fn();
111
+ } finally {
112
+ setActiveConsumer(prevActiveConsumer);
113
+ }
114
+ return output;
115
+ };
116
+ let notificationPhase = false;
117
+ const checkNotInNotificationPhase = () => {
118
+ if (notificationPhase) {
119
+ throw new Error("Reading or writing a signal is forbidden during the notification phase.");
120
+ }
121
+ };
122
+ let epoch = 0;
123
+ class RawStoreWritable {
124
+ constructor(value) {
125
+ this.value = value;
126
+ this.flags = 0;
127
+ this.version = 0;
128
+ this.equalFn = equal;
129
+ this.equalCache = null;
130
+ this.consumerLinks = [];
131
+ }
132
+ newLink(consumer) {
133
+ return {
134
+ version: -1,
135
+ value: void 0,
136
+ producer: this,
137
+ indexInProducer: 0,
138
+ consumer,
139
+ skipMarkDirty: false
140
+ };
141
+ }
142
+ isLinkUpToDate(link) {
143
+ if (link.version === this.version) {
144
+ return true;
145
+ }
146
+ if (link.version === this.version - 1 || link.version < 0) {
147
+ return false;
148
+ }
149
+ let equalCache = this.equalCache;
150
+ if (!equalCache) {
151
+ equalCache = {};
152
+ this.equalCache = equalCache;
153
+ }
154
+ let res = equalCache[link.version];
155
+ if (res === void 0) {
156
+ res = this.equal(link.value, this.value);
157
+ equalCache[link.version] = res;
158
+ }
159
+ return res;
160
+ }
161
+ updateLink(link) {
162
+ link.value = this.value;
163
+ link.version = this.version;
164
+ return this.readValue();
165
+ }
166
+ registerConsumer(link) {
167
+ const consumerLinks = this.consumerLinks;
168
+ const indexInProducer = consumerLinks.length;
169
+ link.indexInProducer = indexInProducer;
170
+ consumerLinks[indexInProducer] = link;
171
+ return link;
172
+ }
173
+ unregisterConsumer(link) {
174
+ const consumerLinks = this.consumerLinks;
175
+ const index = link.indexInProducer;
176
+ if (consumerLinks[index] !== link) {
177
+ throw new Error("assert failed: invalid indexInProducer");
178
+ }
179
+ const lastConsumerLink = consumerLinks.pop();
180
+ const isLast = link === lastConsumerLink;
181
+ if (!isLast) {
182
+ consumerLinks[index] = lastConsumerLink;
183
+ lastConsumerLink.indexInProducer = index;
184
+ } else if (index === 0) {
185
+ this.checkUnused();
186
+ }
187
+ }
188
+ checkUnused() {
189
+ }
190
+ updateValue() {
191
+ }
192
+ equal(a, b) {
193
+ const equalFn = this.equalFn;
194
+ return equalFn(a, b);
195
+ }
196
+ increaseEpoch() {
197
+ epoch++;
198
+ this.markConsumersDirty();
199
+ }
200
+ set(newValue) {
201
+ checkNotInNotificationPhase();
202
+ const same = this.equal(this.value, newValue);
203
+ if (!same) {
204
+ batch(() => {
205
+ this.value = newValue;
206
+ this.version++;
207
+ this.equalCache = null;
208
+ this.increaseEpoch();
209
+ });
210
+ }
211
+ }
212
+ update(updater) {
213
+ this.set(updater(this.value));
214
+ }
215
+ markConsumersDirty() {
216
+ const prevNotificationPhase = notificationPhase;
217
+ notificationPhase = true;
218
+ try {
219
+ const consumerLinks = this.consumerLinks;
220
+ for (let i = 0, l = consumerLinks.length; i < l; i++) {
221
+ const link = consumerLinks[i];
222
+ if (link.skipMarkDirty)
223
+ continue;
224
+ link.consumer.markDirty();
225
+ }
226
+ } finally {
227
+ notificationPhase = prevNotificationPhase;
228
+ }
229
+ }
230
+ get() {
231
+ checkNotInNotificationPhase();
232
+ return activeConsumer ? activeConsumer.addProducer(this) : this.readValue();
233
+ }
234
+ readValue() {
235
+ return this.value;
236
+ }
237
+ subscribe(subscriber) {
238
+ checkNotInNotificationPhase();
239
+ const subscription = new SubscribeConsumer(this, subscriber);
240
+ const unsubscriber = () => subscription.unsubscribe();
241
+ unsubscriber.unsubscribe = unsubscriber;
242
+ return unsubscriber;
243
+ }
244
+ }
245
+ let flushUnusedQueue = null;
246
+ let inFlushUnused = false;
247
+ const flushUnused = () => {
248
+ if (inFlushUnused) {
249
+ throw new Error("assert failed: recursive flushUnused call");
250
+ }
251
+ inFlushUnused = true;
252
+ try {
253
+ const queue = flushUnusedQueue;
254
+ if (queue) {
255
+ flushUnusedQueue = null;
256
+ for (let i = 0, l = queue.length; i < l; i++) {
257
+ const producer = queue[i];
258
+ producer.flags &= ~4;
259
+ producer.checkUnused();
260
+ }
261
+ }
262
+ } finally {
263
+ inFlushUnused = false;
264
+ }
265
+ };
266
+ class RawStoreTrackingUsage extends RawStoreWritable {
267
+ constructor() {
268
+ super(...arguments);
269
+ this.extraUsages = 0;
270
+ }
271
+ updateValue() {
272
+ const flags = this.flags;
273
+ if (!(flags & 2)) {
274
+ if (!this.extraUsages && !this.consumerLinks.length) {
275
+ throw new Error("assert failed: untracked producer usage");
276
+ }
277
+ this.flags |= 2;
278
+ untrack(() => this.startUse());
279
+ }
280
+ }
281
+ checkUnused() {
282
+ const flags = this.flags;
283
+ if (flags & 2 && !this.extraUsages && !this.consumerLinks.length) {
284
+ if (inFlushUnused || flags & 1) {
285
+ this.flags &= ~2;
286
+ untrack(() => this.endUse());
287
+ } else if (!(flags & 4)) {
288
+ this.flags |= 4;
289
+ if (!flushUnusedQueue) {
290
+ flushUnusedQueue = [];
291
+ queueMicrotask(flushUnused);
292
+ }
293
+ flushUnusedQueue.push(this);
294
+ }
295
+ }
296
+ }
297
+ get() {
298
+ checkNotInNotificationPhase();
299
+ if (activeConsumer) {
300
+ return activeConsumer.addProducer(this);
301
+ } else {
302
+ this.extraUsages++;
303
+ try {
304
+ this.updateValue();
305
+ if (this.flags & 16) {
306
+ throw new Error("assert failed: store still dirty after updating it");
307
+ }
308
+ return this.readValue();
309
+ } finally {
310
+ const extraUsages = --this.extraUsages;
311
+ if (extraUsages === 0) {
312
+ this.checkUnused();
313
+ }
314
+ }
315
+ }
316
+ }
317
+ }
318
+ const noopUnsubscribe = () => {
319
+ };
320
+ noopUnsubscribe.unsubscribe = noopUnsubscribe;
321
+ const normalizeUnsubscribe = (unsubscribe) => {
322
+ if (!unsubscribe) {
323
+ return noopUnsubscribe;
324
+ }
325
+ if (unsubscribe.unsubscribe === unsubscribe) {
326
+ return unsubscribe;
327
+ }
328
+ const res = typeof unsubscribe === "function" ? () => unsubscribe() : () => unsubscribe.unsubscribe();
329
+ res.unsubscribe = res;
330
+ return res;
331
+ };
332
+ class RawSubscribableWrapper extends RawStoreTrackingUsage {
333
+ constructor(subscribable) {
334
+ super(void 0);
335
+ this.subscribable = subscribable;
336
+ this.subscriber = this.createSubscriber();
337
+ this.unsubscribe = null;
338
+ this.flags = 1;
339
+ }
340
+ createSubscriber() {
341
+ const subscriber = (value) => this.set(value);
342
+ subscriber.next = subscriber;
343
+ subscriber.pause = () => {
344
+ this.markConsumersDirty();
345
+ };
346
+ return subscriber;
347
+ }
348
+ startUse() {
349
+ this.unsubscribe = normalizeUnsubscribe(this.subscribable.subscribe(this.subscriber));
350
+ }
351
+ endUse() {
352
+ const unsubscribe = this.unsubscribe;
353
+ if (unsubscribe) {
354
+ this.unsubscribe = null;
355
+ unsubscribe();
356
+ }
357
+ }
358
+ }
359
+ const symbolObservable = typeof Symbol === "function" && Symbol.observable || "@@observable";
360
+ const returnThis = function() {
361
+ return this;
362
+ };
363
+ const rawStoreSymbol = Symbol();
364
+ const rawStoreMap = /* @__PURE__ */ new WeakMap();
365
+ const getRawStore = (storeInput) => {
366
+ const rawStore = storeInput[rawStoreSymbol];
367
+ if (rawStore) {
368
+ return rawStore;
369
+ }
370
+ let res = rawStoreMap.get(storeInput);
371
+ if (!res) {
372
+ let subscribable = storeInput;
373
+ if (!("subscribe" in subscribable)) {
374
+ subscribable = subscribable[symbolObservable]();
375
+ }
376
+ res = new RawSubscribableWrapper(subscribable);
377
+ rawStoreMap.set(storeInput, res);
378
+ }
379
+ return res;
380
+ };
381
+ const exposeRawStore = (rawStore, extraProp) => {
382
+ const get = rawStore.get.bind(rawStore);
383
+ if (extraProp) {
384
+ Object.assign(get, extraProp);
385
+ }
386
+ get.get = get;
387
+ get.subscribe = rawStore.subscribe.bind(rawStore);
388
+ get[symbolObservable] = returnThis;
389
+ get[rawStoreSymbol] = rawStore;
390
+ return get;
391
+ };
392
+ const MAX_CHANGE_RECOMPUTES = 1e3;
393
+ const COMPUTED_UNSET = Symbol("UNSET");
394
+ const COMPUTED_ERRORED = Symbol("ERRORED");
395
+ const isComputedSpecialValue = (value) => value === COMPUTED_UNSET || value === COMPUTED_ERRORED;
396
+ class RawStoreComputedOrDerived extends RawStoreTrackingUsage {
397
+ constructor() {
398
+ super(...arguments);
399
+ this.flags = 16;
400
+ }
401
+ equal(a, b) {
402
+ if (isComputedSpecialValue(a) || isComputedSpecialValue(b)) {
403
+ return false;
404
+ }
405
+ return super.equal(a, b);
406
+ }
407
+ markDirty() {
408
+ if (!(this.flags & 16)) {
409
+ this.flags |= 16;
410
+ this.markConsumersDirty();
411
+ }
412
+ }
413
+ readValue() {
414
+ const value = this.value;
415
+ if (value === COMPUTED_ERRORED) {
416
+ throw this.error;
417
+ }
418
+ if (value === COMPUTED_UNSET) {
419
+ throw new Error("assert failed: computed value is not set");
420
+ }
421
+ return value;
422
+ }
423
+ updateValue() {
424
+ if (this.flags & 8) {
425
+ throw new Error("recursive computed");
426
+ }
427
+ super.updateValue();
428
+ if (!(this.flags & 16)) {
429
+ return;
430
+ }
431
+ this.flags |= 8;
432
+ const prevActiveConsumer = setActiveConsumer(null);
433
+ try {
434
+ let iterations = 0;
435
+ do {
436
+ do {
437
+ iterations++;
438
+ this.flags &= ~16;
439
+ if (this.areProducersUpToDate()) {
440
+ return;
441
+ }
442
+ } while (this.flags & 16 && iterations < MAX_CHANGE_RECOMPUTES);
443
+ this.recompute();
444
+ } while (this.flags & 16 && iterations < MAX_CHANGE_RECOMPUTES);
445
+ if (this.flags & 16) {
446
+ this.flags &= ~16;
447
+ this.error = new Error("reached maximum number of store changes in one shot");
448
+ this.set(COMPUTED_ERRORED);
449
+ }
450
+ } finally {
451
+ setActiveConsumer(prevActiveConsumer);
452
+ this.flags &= ~8;
453
+ }
454
+ }
455
+ }
456
+ class RawStoreComputed extends RawStoreComputedOrDerived {
457
+ constructor(computeFn) {
458
+ super(COMPUTED_UNSET);
459
+ this.computeFn = computeFn;
460
+ this.producerIndex = 0;
461
+ this.producerLinks = [];
462
+ this.epoch = -1;
463
+ }
464
+ increaseEpoch() {
465
+ }
466
+ updateValue() {
467
+ const flags = this.flags;
468
+ if (flags & 2 && this.epoch === epoch) {
469
+ return;
470
+ }
471
+ super.updateValue();
472
+ this.epoch = epoch;
473
+ }
474
+ get() {
475
+ if (!activeConsumer && !notificationPhase && this.epoch === epoch && (!(this.flags & 1) || this.flags & 2)) {
476
+ return this.readValue();
477
+ }
478
+ return super.get();
479
+ }
480
+ addProducer(producer) {
481
+ const producerLinks = this.producerLinks;
482
+ const producerIndex = this.producerIndex;
483
+ let link = producerLinks[producerIndex];
484
+ if ((link == null ? void 0 : link.producer) !== producer) {
485
+ if (link) {
486
+ producerLinks.push(link);
487
+ }
488
+ link = producer.registerConsumer(producer.newLink(this));
489
+ }
490
+ producerLinks[producerIndex] = link;
491
+ this.producerIndex = producerIndex + 1;
492
+ updateLinkProducerValue(link);
493
+ if (producer.flags & 1) {
494
+ this.flags |= 1;
495
+ }
496
+ return producer.updateLink(link);
497
+ }
498
+ startUse() {
499
+ const producerLinks = this.producerLinks;
500
+ for (let i = 0, l = producerLinks.length; i < l; i++) {
501
+ const link = producerLinks[i];
502
+ link.producer.registerConsumer(link);
503
+ }
504
+ this.flags |= 16;
505
+ }
506
+ endUse() {
507
+ const producerLinks = this.producerLinks;
508
+ for (let i = 0, l = producerLinks.length; i < l; i++) {
509
+ const link = producerLinks[i];
510
+ link.producer.unregisterConsumer(link);
511
+ }
512
+ }
513
+ areProducersUpToDate() {
514
+ if (this.value === COMPUTED_UNSET) {
515
+ return false;
516
+ }
517
+ const producerLinks = this.producerLinks;
518
+ for (let i = 0, l = producerLinks.length; i < l; i++) {
519
+ const link = producerLinks[i];
520
+ const producer = link.producer;
521
+ updateLinkProducerValue(link);
522
+ if (!producer.isLinkUpToDate(link)) {
523
+ return false;
524
+ }
525
+ }
526
+ return true;
527
+ }
528
+ recompute() {
529
+ let value;
530
+ const prevActiveConsumer = setActiveConsumer(this);
531
+ try {
532
+ this.producerIndex = 0;
533
+ this.flags &= ~1;
534
+ const computeFn = this.computeFn;
535
+ value = computeFn();
536
+ this.error = null;
537
+ } catch (error) {
538
+ value = COMPUTED_ERRORED;
539
+ this.error = error;
540
+ } finally {
541
+ setActiveConsumer(prevActiveConsumer);
542
+ }
543
+ const producerLinks = this.producerLinks;
544
+ const producerIndex = this.producerIndex;
545
+ if (producerIndex < producerLinks.length) {
546
+ for (let i = 0, l = producerLinks.length - producerIndex; i < l; i++) {
547
+ const link = producerLinks.pop();
548
+ link.producer.unregisterConsumer(link);
549
+ }
550
+ }
551
+ this.set(value);
552
+ }
553
+ }
554
+ function asReadable(store, extraProp) {
555
+ return exposeRawStore(getRawStore(store), extraProp);
556
+ }
557
+ function asWritable(store, setOrExtraProps) {
558
+ return asReadable(store, {
559
+ ...setOrExtraProps,
560
+ set: noop,
561
+ update: noop
562
+ });
563
+ }
564
+ const applyStoreOptions = (store, options) => {
565
+ return store;
566
+ };
567
+ function computed(fn, options) {
568
+ return exposeRawStore(applyStoreOptions(new RawStoreComputed(fn)));
569
+ }
570
+ const defaultCollapseConfig = {
571
+ visible: true,
572
+ horizontal: false,
573
+ onVisibleChange: () => {
574
+ },
575
+ onShown: () => {
576
+ },
577
+ onHidden: () => {
578
+ },
579
+ animated: true,
580
+ animatedOnInit: false,
581
+ className: "",
582
+ id: ""
583
+ };
584
+ function getCollapseDefaultConfig() {
585
+ return { ...defaultCollapseConfig };
586
+ }
587
+ const commonCollapseConfigValidator = {
588
+ horizontal: typeBoolean,
589
+ onVisibleChange: typeFunction,
590
+ onHidden: typeFunction,
591
+ onShown: typeFunction,
592
+ animatedOnInit: typeBoolean,
593
+ animated: typeBoolean,
594
+ className: typeString,
595
+ visible: typeBoolean,
596
+ id: typeString
597
+ };
598
+ function createCollapse(config) {
599
+ const [{ animatedOnInit$, animated$, visible$: requestedVisible$, onVisibleChange$, onHidden$, onShown$, horizontal$, id$, ...stateProps }, patch] = writablesForProps(defaultCollapseConfig, config, commonCollapseConfigValidator);
600
+ const currentTransitionFn$ = asWritable(computed(() => horizontal$() ? collapseHorizontalTransition : collapseVerticalTransition));
601
+ const transition = createTransition({
602
+ props: {
603
+ transition: currentTransitionFn$,
604
+ visible: requestedVisible$,
605
+ animated: animated$,
606
+ animatedOnInit: animatedOnInit$,
607
+ onVisibleChange: onVisibleChange$,
608
+ onHidden: onHidden$,
609
+ onShown: onShown$
610
+ }
611
+ });
612
+ const visible$ = transition.stores.visible$;
613
+ const hidden$ = transition.stores.hidden$;
614
+ return {
615
+ ...stateStores({ ...stateProps, visible$, hidden$, horizontal$ }),
616
+ patch,
617
+ api: {
618
+ open: transition.api.show,
619
+ close: transition.api.hide,
620
+ toggle: transition.api.toggle
621
+ },
622
+ directives: {
623
+ collapseDirective: mergeDirectives(
624
+ transition.directives.directive,
625
+ createAttributesDirective(() => ({
626
+ attributes: {
627
+ id: computed(() => id$() || void 0)
628
+ }
629
+ }))
630
+ )
631
+ }
632
+ };
633
+ }
634
+ export {
635
+ createCollapse as c,
636
+ getCollapseDefaultConfig as g
637
+ };