@flemo/core 1.1.1 → 1.2.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.
@@ -12,6 +12,7 @@ interface HistoryStore {
12
12
  addHistory: (history: History) => void;
13
13
  replaceHistory: (index: number) => void;
14
14
  popHistory: (index: number) => void;
15
+ popHistories: (count: number) => void;
15
16
  }
16
17
  declare const useHistoryStore: import('zustand').UseBoundStore<import('zustand').StoreApi<HistoryStore>>;
17
18
  export default useHistoryStore;
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { create as D } from "zustand";
2
- import { pathToRegexp as S, match as Y } from "path-to-regexp";
3
- class B {
1
+ import { create as w } from "zustand";
2
+ import { pathToRegexp as v, match as B } from "path-to-regexp";
3
+ class Q {
4
4
  tasks = /* @__PURE__ */ new Map();
5
5
  instanceId = Date.now().toString();
6
6
  isLocked = !1;
@@ -10,7 +10,7 @@ class B {
10
10
  pendingTaskQueue = [];
11
11
  isProcessingPending = !1;
12
12
  async acquireLock(t) {
13
- for (let s = 0; s < 10; s++) {
13
+ for (let a = 0; a < 10; a++) {
14
14
  if (!this.isLocked)
15
15
  return this.isLocked = !0, this.currentTaskId = t, !0;
16
16
  await new Promise((r) => setTimeout(r, 100));
@@ -25,8 +25,8 @@ class B {
25
25
  }
26
26
  emitSignal(t) {
27
27
  const e = this.signalListeners.get(t);
28
- e && (e.forEach((a) => {
29
- this.resolveTask(a);
28
+ e && (e.forEach((s) => {
29
+ this.resolveTask(s);
30
30
  }), this.signalListeners.delete(t));
31
31
  }
32
32
  // 대기 중인 태스크들을 처리하는 메서드
@@ -53,7 +53,7 @@ class B {
53
53
  return new Promise((t) => {
54
54
  const e = () => {
55
55
  this.pendingTaskQueue.filter(
56
- (s) => s.status === "MANUAL_PENDING" || s.status === "SIGNAL_PENDING"
56
+ (a) => a.status === "MANUAL_PENDING" || a.status === "SIGNAL_PENDING"
57
57
  ).length === 0 ? t() : setTimeout(e, 100);
58
58
  };
59
59
  e();
@@ -61,15 +61,15 @@ class B {
61
61
  }
62
62
  // 태스크 상태 변경 시 대기 큐 처리
63
63
  async onTaskStatusChange(t, e) {
64
- (e === "COMPLETED" || e === "FAILED" || e === "ROLLEDBACK") && (this.pendingTaskQueue = this.pendingTaskQueue.filter((a) => a.id !== t), await this.processPendingTasks());
64
+ (e === "COMPLETED" || e === "FAILED" || e === "ROLLEDBACK") && (this.pendingTaskQueue = this.pendingTaskQueue.filter((s) => s.id !== t), await this.processPendingTasks());
65
65
  }
66
66
  async addTask(t, e = {}) {
67
- const a = e.id || this.generateTaskId();
68
- return new Promise((s, r) => {
67
+ const s = e.id || this.generateTaskId();
68
+ return new Promise((a, r) => {
69
69
  this.taskQueue = this.taskQueue.then(async () => {
70
70
  try {
71
- const { control: o, validate: c, rollback: l, dependencies: u = [], delay: d } = e, m = new AbortController(), i = {
72
- id: a,
71
+ const { control: o, validate: c, rollback: l, dependencies: u = [], delay: d } = e, p = new AbortController(), i = {
72
+ id: s,
73
73
  execute: t,
74
74
  timestamp: Date.now(),
75
75
  retryCount: 0,
@@ -79,9 +79,9 @@ class B {
79
79
  validate: c,
80
80
  rollback: l,
81
81
  control: o,
82
- abortController: m
82
+ abortController: p
83
83
  };
84
- this.tasks.set(i.id, i), this.pendingTaskQueue.length > 0 && (this.pendingTaskQueue.push(i), await this.waitForPendingTasks(), this.pendingTaskQueue = this.pendingTaskQueue.filter((g) => g.id !== i.id));
84
+ this.tasks.set(i.id, i), this.pendingTaskQueue.length > 0 && (this.pendingTaskQueue.push(i), await this.waitForPendingTasks(), this.pendingTaskQueue = this.pendingTaskQueue.filter((P) => P.id !== i.id));
85
85
  try {
86
86
  if (!await this.acquireLock(i.id))
87
87
  throw i.status = "FAILED", new Error("FAILED");
@@ -95,9 +95,9 @@ class B {
95
95
  if (i.validate && !await i.validate())
96
96
  throw i.status = "FAILED", new Error("FAILED");
97
97
  d && d > 0 && await new Promise((f) => setTimeout(f, d));
98
- const p = await i.execute(i.abortController);
98
+ const h = await i.execute(i.abortController);
99
99
  if (i.abortController.signal.aborted) {
100
- i.status = "COMPLETED", await this.onTaskStatusChange(i.id, "COMPLETED"), s({
100
+ i.status = "COMPLETED", await this.onTaskStatusChange(i.id, "COMPLETED"), a({
101
101
  success: !0,
102
102
  result: void 0,
103
103
  taskId: i.id,
@@ -109,37 +109,37 @@ class B {
109
109
  if (e.control) {
110
110
  const f = e.control;
111
111
  if (f.delay && f.delay > 0 && await new Promise((y) => setTimeout(y, f.delay)), f.manual) {
112
- i.status = "MANUAL_PENDING", i.manualResolver = { resolve: s, reject: r, result: p }, this.pendingTaskQueue.push(i), await this.onTaskStatusChange(i.id, "MANUAL_PENDING");
112
+ i.status = "MANUAL_PENDING", i.manualResolver = { resolve: a, reject: r, result: h }, this.pendingTaskQueue.push(i), await this.onTaskStatusChange(i.id, "MANUAL_PENDING");
113
113
  return;
114
114
  }
115
115
  if (f.signal) {
116
- i.status = "SIGNAL_PENDING", i.manualResolver = { resolve: s, reject: r, result: p }, this.signalListeners.has(f.signal) || this.signalListeners.set(f.signal, /* @__PURE__ */ new Set()), this.signalListeners.get(f.signal).add(i.id), this.pendingTaskQueue.push(i), await this.onTaskStatusChange(i.id, "SIGNAL_PENDING");
116
+ i.status = "SIGNAL_PENDING", i.manualResolver = { resolve: a, reject: r, result: h }, this.signalListeners.has(f.signal) || this.signalListeners.set(f.signal, /* @__PURE__ */ new Set()), this.signalListeners.get(f.signal).add(i.id), this.pendingTaskQueue.push(i), await this.onTaskStatusChange(i.id, "SIGNAL_PENDING");
117
117
  return;
118
118
  }
119
119
  if (f.condition && !await f.condition()) {
120
- i.status = "MANUAL_PENDING", i.manualResolver = { resolve: s, reject: r, result: p }, this.pendingTaskQueue.push(i), await this.onTaskStatusChange(i.id, "MANUAL_PENDING");
120
+ i.status = "MANUAL_PENDING", i.manualResolver = { resolve: a, reject: r, result: h }, this.pendingTaskQueue.push(i), await this.onTaskStatusChange(i.id, "MANUAL_PENDING");
121
121
  return;
122
122
  }
123
123
  }
124
- i.status = "COMPLETED", await this.onTaskStatusChange(i.id, "COMPLETED"), s({
124
+ i.status = "COMPLETED", await this.onTaskStatusChange(i.id, "COMPLETED"), a({
125
125
  success: !0,
126
- result: p,
126
+ result: h,
127
127
  taskId: i.id,
128
128
  timestamp: Date.now(),
129
129
  instanceId: this.instanceId
130
130
  });
131
- } catch (p) {
131
+ } catch (h) {
132
132
  if (i.status = "FAILED", i.rollback)
133
133
  try {
134
134
  await i.rollback(), i.status = "ROLLEDBACK";
135
135
  } catch {
136
136
  }
137
- throw await this.onTaskStatusChange(i.id, i.status), p;
137
+ throw await this.onTaskStatusChange(i.id, i.status), h;
138
138
  } finally {
139
139
  this.releaseLock(i.id);
140
140
  }
141
- } catch (g) {
142
- r(g);
141
+ } catch (P) {
142
+ r(P);
143
143
  }
144
144
  } catch (o) {
145
145
  r(o);
@@ -155,10 +155,10 @@ class B {
155
155
  if (e.control?.condition && !await e.control.condition())
156
156
  return !1;
157
157
  e.status = "COMPLETED";
158
- const a = e.manualResolver;
159
- return a.resolve({
158
+ const s = e.manualResolver;
159
+ return s.resolve({
160
160
  success: !0,
161
- result: a.result,
161
+ result: s.result,
162
162
  taskId: e.id,
163
163
  timestamp: Date.now(),
164
164
  instanceId: this.instanceId
@@ -173,7 +173,7 @@ class B {
173
173
  await Promise.all(t.map((e) => this.resolveTask(e.id)));
174
174
  }
175
175
  }
176
- const pt = new B(), yt = D((n) => ({
176
+ const yt = new Q(), Pt = w((n) => ({
177
177
  index: -1,
178
178
  histories: [],
179
179
  addHistory: (t) => n((e) => ({
@@ -186,27 +186,40 @@ const pt = new B(), yt = D((n) => ({
186
186
  })),
187
187
  popHistory: (t) => n((e) => ({
188
188
  index: e.index - 1,
189
- histories: e.histories.filter((a, s) => s !== t)
190
- }))
191
- })), gt = D((n) => ({
189
+ histories: e.histories.filter((s, a) => a !== t)
190
+ })),
191
+ // Drop `count` entries sitting directly below the current top, keeping the
192
+ // top itself. Used by pop(n) to remove the screens it skips over in the same
193
+ // synchronous block that starts the transition — so they never paint — while
194
+ // the leaving top stays mounted to drive and resolve the animation.
195
+ popHistories: (t) => {
196
+ t <= 0 || n((e) => {
197
+ const s = e.index;
198
+ return {
199
+ index: e.index - t,
200
+ histories: e.histories.filter((a, r) => r < s - t || r >= s)
201
+ };
202
+ });
203
+ }
204
+ })), gt = w((n) => ({
192
205
  status: "IDLE",
193
206
  transitionTaskId: null,
194
207
  setStatus: (t) => n({ status: t }),
195
208
  setTransitionTaskId: (t) => n({ transitionTaskId: t })
196
209
  }));
197
- let N = 0;
198
- function Pt() {
199
- N += 1;
210
+ let L = 0;
211
+ function It() {
212
+ L += 1;
200
213
  }
201
214
  function Et() {
202
- return N > 0 ? (N -= 1, !0) : !1;
215
+ return L > 0 ? (L -= 1, !0) : !1;
203
216
  }
204
- function k({
217
+ function T({
205
218
  name: n,
206
219
  initial: t,
207
220
  idle: e,
208
- enter: a,
209
- enterBack: s,
221
+ enter: s,
222
+ enterBack: a,
210
223
  exit: r,
211
224
  exitBack: o,
212
225
  options: c
@@ -218,30 +231,30 @@ function k({
218
231
  "IDLE-true": e,
219
232
  "IDLE-false": e,
220
233
  "PUSHING-false": r,
221
- "PUSHING-true": a,
234
+ "PUSHING-true": s,
222
235
  "REPLACING-false": r,
223
- "REPLACING-true": a,
236
+ "REPLACING-true": s,
224
237
  "POPPING-false": o,
225
- "POPPING-true": s,
238
+ "POPPING-true": a,
226
239
  "COMPLETED-false": r,
227
- "COMPLETED-true": a
240
+ "COMPLETED-true": s
228
241
  },
229
242
  ...c
230
243
  };
231
244
  }
232
- function It({
245
+ function kt({
233
246
  name: n,
234
247
  initial: t,
235
248
  idle: e,
236
- pushOnEnter: a,
237
- pushOnExit: s,
249
+ pushOnEnter: s,
250
+ pushOnExit: a,
238
251
  replaceOnEnter: r,
239
252
  replaceOnExit: o,
240
253
  popOnEnter: c,
241
254
  popOnExit: l,
242
255
  completedOnExit: u,
243
256
  completedOnEnter: d,
244
- options: m
257
+ options: p
245
258
  }) {
246
259
  return {
247
260
  name: n,
@@ -249,8 +262,8 @@ function It({
249
262
  variants: {
250
263
  "IDLE-true": e,
251
264
  "IDLE-false": e,
252
- "PUSHING-false": s,
253
- "PUSHING-true": a,
265
+ "PUSHING-false": a,
266
+ "PUSHING-true": s,
254
267
  "REPLACING-false": o,
255
268
  "REPLACING-true": r,
256
269
  "POPPING-false": l,
@@ -258,15 +271,15 @@ function It({
258
271
  "COMPLETED-false": u,
259
272
  "COMPLETED-true": d
260
273
  },
261
- ...m
274
+ ...p
262
275
  };
263
276
  }
264
- const Q = (n, t, e) => {
265
- const [a, s] = t, [r, o] = e;
266
- if (s === a) return r;
267
- const c = (n - a) / (s - a);
277
+ const X = (n, t, e) => {
278
+ const [s, a] = t, [r, o] = e;
279
+ if (a === s) return r;
280
+ const c = (n - s) / (a - s);
268
281
  return r + c * (o - r);
269
- }, X = k({
282
+ }, F = T({
270
283
  name: "cupertino",
271
284
  initial: {
272
285
  x: "100%"
@@ -299,7 +312,7 @@ const Q = (n, t, e) => {
299
312
  },
300
313
  exit: {
301
314
  value: {
302
- x: -100
315
+ x: "-30%"
303
316
  },
304
317
  options: {
305
318
  duration: 0.7,
@@ -319,10 +332,10 @@ const Q = (n, t, e) => {
319
332
  decoratorName: "overlay",
320
333
  swipeDirection: "x",
321
334
  onSwipeStart: async () => !0,
322
- onSwipe: (n, t, { animate: e, currentScreen: a, prevScreen: s, onProgress: r }) => {
323
- const { offset: o } = t, c = o.x, l = Q(c, [0, window.innerWidth], [0, 100]);
335
+ onSwipe: (n, t, { animate: e, currentScreen: s, prevScreen: a, onProgress: r }) => {
336
+ const { offset: o } = t, c = o.x, l = X(c, [0, window.innerWidth], [0, 100]);
324
337
  return r?.(!0, l), e(
325
- a,
338
+ s,
326
339
  {
327
340
  x: Math.max(0, c)
328
341
  },
@@ -330,20 +343,20 @@ const Q = (n, t, e) => {
330
343
  duration: 0
331
344
  }
332
345
  ), e(
333
- s,
346
+ a,
334
347
  {
335
- x: -100 + l
348
+ x: `${-30 + l * 0.3}%`
336
349
  },
337
350
  {
338
351
  duration: 0
339
352
  }
340
353
  ), l;
341
354
  },
342
- onSwipeEnd: async (n, t, { animate: e, currentScreen: a, prevScreen: s, onStart: r }) => {
355
+ onSwipeEnd: async (n, t, { animate: e, currentScreen: s, prevScreen: a, onStart: r }) => {
343
356
  const { offset: o, velocity: c } = t, u = o.x > 50 || c.x > 20;
344
357
  return r?.(u), await Promise.all([
345
358
  e(
346
- a,
359
+ s,
347
360
  {
348
361
  x: u ? "100%" : 0
349
362
  },
@@ -353,9 +366,9 @@ const Q = (n, t, e) => {
353
366
  }
354
367
  ),
355
368
  e(
356
- s,
369
+ a,
357
370
  {
358
- x: u ? 0 : -100
371
+ x: u ? 0 : "-30%"
359
372
  },
360
373
  {
361
374
  duration: 0.3,
@@ -365,12 +378,12 @@ const Q = (n, t, e) => {
365
378
  ]), u;
366
379
  }
367
380
  }
368
- }), F = (n, t, e) => {
369
- const [a, s] = t, [r, o] = e;
370
- if (s === a) return r;
371
- const c = (n - a) / (s - a);
381
+ }), z = (n, t, e) => {
382
+ const [s, a] = t, [r, o] = e;
383
+ if (a === s) return r;
384
+ const c = (n - s) / (a - s);
372
385
  return r + c * (o - r);
373
- }, z = k({
386
+ }, V = T({
374
387
  name: "layout",
375
388
  initial: {
376
389
  opacity: 0.97
@@ -419,10 +432,10 @@ const Q = (n, t, e) => {
419
432
  decoratorName: "overlay",
420
433
  swipeDirection: "y",
421
434
  onSwipeStart: async () => !0,
422
- onSwipe: (n, t, { animate: e, currentScreen: a, onProgress: s }) => {
423
- const { offset: r } = t, o = r.y, c = Math.max(0, Math.min(56, o)), l = F(c, [0, 56], [1, 0.96]), u = Math.max(0, o - 56), d = Math.min(1, u / 160), m = Math.sqrt(d) * 12, i = Math.max(0, c + m), h = Math.min(56, i);
424
- return s?.(!0, 100), e(
425
- a,
435
+ onSwipe: (n, t, { animate: e, currentScreen: s, onProgress: a }) => {
436
+ const { offset: r } = t, o = r.y, c = Math.max(0, Math.min(56, o)), l = z(c, [0, 56], [1, 0.96]), u = Math.max(0, o - 56), d = Math.min(1, u / 160), p = Math.sqrt(d) * 12, i = Math.max(0, c + p), m = Math.min(56, i);
437
+ return a?.(!0, 100), e(
438
+ s,
426
439
  {
427
440
  y: i,
428
441
  opacity: l
@@ -430,13 +443,13 @@ const Q = (n, t, e) => {
430
443
  {
431
444
  duration: 0
432
445
  }
433
- ), h;
446
+ ), m;
434
447
  },
435
- onSwipeEnd: async (n, t, { animate: e, currentScreen: a, prevScreen: s, onStart: r }) => {
448
+ onSwipeEnd: async (n, t, { animate: e, currentScreen: s, prevScreen: a, onStart: r }) => {
436
449
  const { offset: o, velocity: c } = t, u = o.y > 56 || c.y > 20;
437
450
  return r?.(u), await Promise.all([
438
451
  e(
439
- a,
452
+ s,
440
453
  {
441
454
  y: u ? "100%" : 0,
442
455
  opacity: u ? 0.96 : 1
@@ -446,7 +459,7 @@ const Q = (n, t, e) => {
446
459
  }
447
460
  ),
448
461
  e(
449
- s,
462
+ a,
450
463
  {
451
464
  y: 0,
452
465
  opacity: u ? 1 : 0.97
@@ -458,14 +471,15 @@ const Q = (n, t, e) => {
458
471
  ]), u;
459
472
  }
460
473
  }
461
- }), V = k({
474
+ }), Z = T({
462
475
  name: "material",
463
476
  initial: {
464
477
  y: "100%"
465
478
  },
466
479
  idle: {
467
480
  value: {
468
- y: 0
481
+ y: 0,
482
+ opacity: 1
469
483
  },
470
484
  options: {
471
485
  duration: 0
@@ -491,7 +505,8 @@ const Q = (n, t, e) => {
491
505
  },
492
506
  exit: {
493
507
  value: {
494
- y: -56
508
+ y: -56,
509
+ opacity: 0
495
510
  },
496
511
  options: {
497
512
  duration: 0.35,
@@ -500,7 +515,8 @@ const Q = (n, t, e) => {
500
515
  },
501
516
  exitBack: {
502
517
  value: {
503
- y: 0
518
+ y: 0,
519
+ opacity: 1
504
520
  },
505
521
  options: {
506
522
  duration: 0.25,
@@ -510,10 +526,10 @@ const Q = (n, t, e) => {
510
526
  options: {
511
527
  swipeDirection: "y",
512
528
  onSwipeStart: async () => !0,
513
- onSwipe: (n, t, { animate: e, currentScreen: a, prevScreen: s, onProgress: r }) => {
514
- const { offset: o } = t, c = o.y, l = Math.max(0, Math.min(56, c)), u = Math.max(0, c - 56), d = Math.min(1, u / 160), m = Math.sqrt(d) * 12, i = Math.max(0, l + m), h = Math.min(56, i);
515
- return r?.(!0, h), e(
516
- a,
529
+ onSwipe: (n, t, { animate: e, currentScreen: s, prevScreen: a, onProgress: r }) => {
530
+ const { offset: o } = t, c = o.y, l = Math.max(0, Math.min(56, c)), u = Math.max(0, c - 56), d = Math.min(1, u / 160), p = Math.sqrt(d) * 12, i = Math.max(0, l + p), m = Math.min(56, i);
531
+ return r?.(!0, m), e(
532
+ s,
517
533
  {
518
534
  y: i
519
535
  },
@@ -521,18 +537,19 @@ const Q = (n, t, e) => {
521
537
  duration: 0
522
538
  }
523
539
  ), e(
524
- s,
540
+ a,
525
541
  {
526
- y: -56 + h
542
+ y: -56 + m,
543
+ opacity: m / 56
527
544
  },
528
545
  { duration: 0 }
529
- ), h;
546
+ ), m;
530
547
  },
531
- onSwipeEnd: async (n, t, { animate: e, currentScreen: a, prevScreen: s, onStart: r }) => {
548
+ onSwipeEnd: async (n, t, { animate: e, currentScreen: s, prevScreen: a, onStart: r }) => {
532
549
  const { offset: o, velocity: c } = t, u = o.y > 56 || c.y > 20;
533
550
  return r?.(u), await Promise.all([
534
551
  e(
535
- a,
552
+ s,
536
553
  {
537
554
  y: u ? "100%" : 0
538
555
  },
@@ -542,9 +559,10 @@ const Q = (n, t, e) => {
542
559
  }
543
560
  ),
544
561
  e(
545
- s,
562
+ a,
546
563
  {
547
- y: u ? 0 : -56
564
+ y: u ? 0 : -56,
565
+ opacity: u ? 1 : 0
548
566
  },
549
567
  {
550
568
  duration: u ? 0.22 : 0.24,
@@ -554,7 +572,7 @@ const Q = (n, t, e) => {
554
572
  ]), u;
555
573
  }
556
574
  }
557
- }), Z = k({
575
+ }), j = T({
558
576
  name: "none",
559
577
  initial: {},
560
578
  idle: {
@@ -587,21 +605,21 @@ const Q = (n, t, e) => {
587
605
  duration: 0
588
606
  }
589
607
  }
590
- }), kt = /* @__PURE__ */ new Map([
591
- ["none", Z],
592
- ["cupertino", X],
593
- ["material", V],
594
- ["layout", z]
595
- ]), Tt = D((n) => ({
608
+ }), Tt = /* @__PURE__ */ new Map([
609
+ ["none", j],
610
+ ["cupertino", F],
611
+ ["material", Z],
612
+ ["layout", V]
613
+ ]), Nt = w((n) => ({
596
614
  defaultTransitionName: "cupertino",
597
615
  setDefaultTransitionName: (t) => n({ defaultTransitionName: t })
598
616
  }));
599
- function j({
617
+ function K({
600
618
  name: n,
601
619
  initial: t,
602
620
  idle: e,
603
- enter: a,
604
- exit: s,
621
+ enter: s,
622
+ exit: a,
605
623
  options: r
606
624
  }) {
607
625
  return {
@@ -611,30 +629,30 @@ function j({
611
629
  "IDLE-true": e,
612
630
  "IDLE-false": e,
613
631
  "PUSHING-true": e,
614
- "PUSHING-false": a,
632
+ "PUSHING-false": s,
615
633
  "REPLACING-true": e,
616
- "REPLACING-false": a,
634
+ "REPLACING-false": s,
617
635
  "POPPING-true": e,
618
- "POPPING-false": s,
636
+ "POPPING-false": a,
619
637
  "COMPLETED-true": e,
620
- "COMPLETED-false": a
638
+ "COMPLETED-false": s
621
639
  },
622
640
  ...r
623
641
  };
624
642
  }
625
- function Nt({
643
+ function Lt({
626
644
  name: n,
627
645
  initial: t,
628
646
  idle: e,
629
- pushOnEnter: a,
630
- pushOnExit: s,
647
+ pushOnEnter: s,
648
+ pushOnExit: a,
631
649
  replaceOnEnter: r,
632
650
  replaceOnExit: o,
633
651
  popOnEnter: c,
634
652
  popOnExit: l,
635
653
  completedOnEnter: u,
636
654
  completedOnExit: d,
637
- options: m
655
+ options: p
638
656
  }) {
639
657
  return {
640
658
  name: n,
@@ -642,8 +660,8 @@ function Nt({
642
660
  variants: {
643
661
  "IDLE-true": e,
644
662
  "IDLE-false": e,
645
- "PUSHING-false": s,
646
- "PUSHING-true": a,
663
+ "PUSHING-false": a,
664
+ "PUSHING-true": s,
647
665
  "REPLACING-false": o,
648
666
  "REPLACING-true": r,
649
667
  "POPPING-false": l,
@@ -651,19 +669,19 @@ function Nt({
651
669
  "COMPLETED-false": d,
652
670
  "COMPLETED-true": u
653
671
  },
654
- ...m
672
+ ...p
655
673
  };
656
674
  }
657
- const K = j({
675
+ const I = "rgba(0, 0, 0, 0.3)", q = K({
658
676
  name: "overlay",
659
677
  initial: {
660
678
  opacity: 0,
661
- backgroundColor: "rgba(0, 0, 0, 0)"
679
+ backgroundColor: I
662
680
  },
663
681
  idle: {
664
682
  value: {
665
683
  opacity: 0,
666
- backgroundColor: "rgba(0, 0, 0, 0)"
684
+ backgroundColor: I
667
685
  },
668
686
  options: {
669
687
  duration: 0
@@ -671,25 +689,35 @@ const K = j({
671
689
  },
672
690
  // Visible dim — applied when this screen is the one going behind / sitting
673
691
  // behind a new active screen (PUSHING-false / REPLACING-false / COMPLETED-false).
692
+ // Duration matches cupertino's enter so the dim resolves in lockstep with the
693
+ // underlying screen slide (and there's no animation-vs-hold-by-fill window for
694
+ // the rest-rule handoff to race against — that's a function of duration + fill,
695
+ // not the curve). Easing is intentionally left at the default: this animates
696
+ // `opacity` (a luminance channel), not position, so cupertino's positional
697
+ // decelerate curve would front-load the darkening into an abrupt step with a
698
+ // long invisible tail. The default ease spreads the perceived dim evenly across
699
+ // the duration, matching this decorator's linear-perceived-ramp design (see the
700
+ // DIM_COLOR note above).
674
701
  enter: {
675
702
  value: {
676
703
  opacity: 1,
677
- backgroundColor: "rgba(0, 0, 0, 0.3)"
704
+ backgroundColor: I
678
705
  },
679
706
  options: {
680
- duration: 0.3
707
+ duration: 0.7
681
708
  }
682
709
  },
683
710
  // POPPING-false target: the previously-behind screen is returning to active.
684
711
  // Fades from `enter` (visible dim) back to invisible so the overlay clears
685
- // before the screen lands at COMPLETED-true (= idle).
712
+ // before the screen lands at COMPLETED-true (= idle). Mirrors cupertino's
713
+ // enterBack (the returning screen's slide-in) duration.
686
714
  exit: {
687
715
  value: {
688
716
  opacity: 0,
689
- backgroundColor: "rgba(0, 0, 0, 0)"
717
+ backgroundColor: I
690
718
  },
691
719
  options: {
692
- duration: 0.3
720
+ duration: 0.6
693
721
  }
694
722
  },
695
723
  options: {
@@ -702,8 +730,8 @@ const K = j({
702
730
  duration: 0.3
703
731
  }
704
732
  ),
705
- onSwipe: (n, t, { animate: e, prevDecorator: a }) => e(
706
- a,
733
+ onSwipe: (n, t, { animate: e, prevDecorator: s }) => e(
734
+ s,
707
735
  {
708
736
  opacity: Math.max(0, 1 - t / 100)
709
737
  },
@@ -721,7 +749,7 @@ const K = j({
721
749
  }
722
750
  )
723
751
  }
724
- }), Lt = /* @__PURE__ */ new Map([["overlay", K]]), I = {
752
+ }), Dt = /* @__PURE__ */ new Map([["overlay", q]]), k = {
725
753
  "IDLE-true": "self",
726
754
  "IDLE-false": "self",
727
755
  "PUSHING-true": "initial",
@@ -732,7 +760,7 @@ const K = j({
732
760
  "POPPING-false": "PUSHING-false",
733
761
  "COMPLETED-true": "self",
734
762
  "COMPLETED-false": "self"
735
- }, G = Object.keys(I), q = G, W = (n) => n.replace(/[^a-zA-Z0-9_-]/g, "_"), O = (n) => typeof n == "object" && n !== null && !Array.isArray(n), J = /* @__PURE__ */ new Set([
763
+ }, O = Object.keys(k), W = O, J = (n) => n.replace(/[^a-zA-Z0-9_-]/g, "_"), b = (n) => typeof n == "object" && n !== null && !Array.isArray(n), tt = /* @__PURE__ */ new Set([
736
764
  "opacity",
737
765
  "scale",
738
766
  "scaleX",
@@ -769,7 +797,7 @@ const K = j({
769
797
  "strokeDashoffset",
770
798
  "strokeMiterlimit",
771
799
  "strokeWidth"
772
- ]), tt = (n, t) => t.startsWith("--") ? `${n}` : J.has(t) ? `${n}` : t === "rotate" || t === "rotateX" || t === "rotateY" || t === "rotateZ" ? `${n}deg` : `${n}px`, b = (n, t) => typeof t == "number" ? tt(t, n) : typeof t == "string" ? t : "", $ = (n) => n.replace(/[A-Z]/g, (t) => `-${t.toLowerCase()}`), R = /* @__PURE__ */ new Set([
800
+ ]), et = (n, t) => t.startsWith("--") ? `${n}` : tt.has(t) ? `${n}` : t === "rotate" || t === "rotateX" || t === "rotateY" || t === "rotateZ" ? `${n}deg` : `${n}px`, $ = (n, t) => typeof t == "number" ? et(t, n) : typeof t == "string" ? t : "", R = (n) => n.replace(/[A-Z]/g, (t) => `-${t.toLowerCase()}`), _ = /* @__PURE__ */ new Set([
773
801
  "x",
774
802
  "y",
775
803
  "z",
@@ -780,7 +808,7 @@ const K = j({
780
808
  "rotateX",
781
809
  "rotateY",
782
810
  "rotateZ"
783
- ]), et = /^-?0(\.0+)?(px|%|em|rem|vh|vw|vmin|vmax)?$/, nt = /^-?0(\.0+)?(deg|rad|grad|turn)?$/, at = /^1(\.0+)?$/, st = (n, t) => n === "scale" || n === "scaleX" || n === "scaleY" ? t === 1 ? !0 : typeof t == "string" ? at.test(t.trim()) : !1 : n === "rotate" || n === "rotateX" || n === "rotateY" || n === "rotateZ" ? t === 0 ? !0 : typeof t == "string" ? nt.test(t.trim()) : !1 : t === 0 ? !0 : typeof t == "string" ? et.test(t.trim()) : !1, rt = (n, t) => {
811
+ ]), nt = /^-?0(\.0+)?(px|%|em|rem|vh|vw|vmin|vmax)?$/, st = /^-?0(\.0+)?(deg|rad|grad|turn)?$/, at = /^1(\.0+)?$/, rt = (n, t) => n === "scale" || n === "scaleX" || n === "scaleY" ? t === 1 ? !0 : typeof t == "string" ? at.test(t.trim()) : !1 : n === "rotate" || n === "rotateX" || n === "rotateY" || n === "rotateZ" ? t === 0 ? !0 : typeof t == "string" ? st.test(t.trim()) : !1 : t === 0 ? !0 : typeof t == "string" ? nt.test(t.trim()) : !1, ot = (n, t) => {
784
812
  switch (n) {
785
813
  case "x":
786
814
  return `translateX(${t})`;
@@ -804,35 +832,35 @@ const K = j({
804
832
  default:
805
833
  return "";
806
834
  }
807
- }, Dt = (n) => {
835
+ }, wt = (n) => {
808
836
  const t = /* @__PURE__ */ new Set();
809
837
  let e = !1;
810
- const a = (s) => {
811
- if (O(s))
812
- for (const r of Object.keys(s)) {
813
- const o = s[r];
814
- b(r, o) !== "" && (R.has(r) ? e = !0 : t.add($(r)));
838
+ const s = (a) => {
839
+ if (b(a))
840
+ for (const r of Object.keys(a)) {
841
+ const o = a[r];
842
+ $(r, o) !== "" && (_.has(r) ? e = !0 : t.add(R(r)));
815
843
  }
816
844
  };
817
- a(n.initial);
818
- for (const s of Object.values(n.variants))
819
- a(s.value);
845
+ s(n.initial);
846
+ for (const a of Object.values(n.variants))
847
+ s(a.value);
820
848
  return e && t.add("transform"), Array.from(t);
821
- }, P = (n) => {
822
- if (!O(n)) return [];
849
+ }, g = (n) => {
850
+ if (!b(n)) return [];
823
851
  const t = [];
824
852
  let e = !0;
825
- const a = [];
826
- for (const s of Object.keys(n)) {
827
- const r = n[s], o = b(s, r);
828
- o !== "" && (R.has(s) ? (t.push(rt(s, o)), st(s, r) || (e = !1)) : a.push({ property: $(s), value: o }));
853
+ const s = [];
854
+ for (const a of Object.keys(n)) {
855
+ const r = n[a], o = $(a, r);
856
+ o !== "" && (_.has(a) ? (t.push(ot(a, o)), rt(a, r) || (e = !1)) : s.push({ property: R(a), value: o }));
829
857
  }
830
- return t.length > 0 && a.push({
858
+ return t.length > 0 && s.push({
831
859
  property: "transform",
832
860
  value: e ? "none" : t.join(" ")
833
- }), a;
861
+ }), s;
834
862
  }, E = (n) => n.map((t) => ` ${t.property}: ${t.value};`).join(`
835
- `), ot = (n) => Array.isArray(n) ? n.length === 4 && n.every((t) => typeof t == "number") ? `cubic-bezier(${n.join(", ")})` : "linear" : typeof n == "string" ? {
863
+ `), it = (n) => Array.isArray(n) ? n.length === 4 && n.every((t) => typeof t == "number") ? `cubic-bezier(${n.join(", ")})` : "linear" : typeof n == "string" ? {
836
864
  linear: "linear",
837
865
  easeIn: "ease-in",
838
866
  easeOut: "ease-out",
@@ -842,22 +870,22 @@ const K = j({
842
870
  backIn: "cubic-bezier(0.31, 0.01, 0.66, -0.59)",
843
871
  backOut: "cubic-bezier(0.33, 1.53, 0.69, 0.99)",
844
872
  anticipate: "cubic-bezier(0.36, 0, 0.66, -0.56)"
845
- }[n] ?? "ease" : "ease", _ = (n) => {
873
+ }[n] ?? "ease" : "ease", H = (n) => {
846
874
  if (!n) return 0;
847
875
  const t = n.duration;
848
876
  return typeof t == "number" && t >= 0 ? t : 0;
849
- }, H = (n) => n && typeof n.delay == "number" && n.delay > 0 ? n.delay : 0, v = (n, t) => {
850
- const [e, a] = t.split("-");
851
- return `[data-flemo-screen][data-flemo-transition="${n}"][data-flemo-status="${e}"][data-flemo-active="${a}"]`;
852
- }, A = (n, t) => {
853
- const [e, a] = t.split("-");
854
- return `[data-flemo-decorator][data-flemo-decorator-name="${n}"][data-flemo-status="${e}"][data-flemo-active="${a}"]`;
855
- }, it = (n, t) => {
856
- const [e, a] = t.split("-");
857
- return `[data-flemo-bar][data-flemo-bar-transition="${n}"][data-flemo-bar-status="${e}"][data-flemo-bar-active="${a}"][data-flemo-bar-riding="true"]`;
858
- }, ct = (n, t, e) => `flemo-${n}-${W(t)}-${e}`, M = (n, t, e, a, s, r) => {
859
- const o = P(a), c = P(s.value), l = _(s.options), u = H(s.options), d = ot(s.options?.ease), m = r(t, e), i = n === "screen" ? `${m},
860
- ${it(t, e)}` : m;
877
+ }, U = (n) => n && typeof n.delay == "number" && n.delay > 0 ? n.delay : 0, A = (n, t) => {
878
+ const [e, s] = t.split("-");
879
+ return `[data-flemo-screen][data-flemo-transition="${n}"][data-flemo-status="${e}"][data-flemo-active="${s}"]`;
880
+ }, M = (n, t) => {
881
+ const [e, s] = t.split("-");
882
+ return `[data-flemo-decorator][data-flemo-decorator-name="${n}"][data-flemo-status="${e}"][data-flemo-active="${s}"]`;
883
+ }, ct = (n, t) => {
884
+ const [e, s] = t.split("-");
885
+ return `[data-flemo-bar][data-flemo-bar-transition="${n}"][data-flemo-bar-status="${e}"][data-flemo-bar-active="${s}"][data-flemo-bar-riding="true"]`;
886
+ }, ut = (n, t, e) => `flemo-${n}-${J(t)}-${e}`, x = (n, t, e, s, a, r) => {
887
+ const o = g(s), c = g(a.value), l = H(a.options), u = U(a.options), d = it(a.options?.ease), p = r(t, e), i = n === "screen" ? `${p},
888
+ ${ct(t, e)}` : p;
861
889
  if (c.length === 0 && o.length === 0)
862
890
  return "";
863
891
  if (l <= 0 && u <= 0)
@@ -865,8 +893,8 @@ ${it(t, e)}` : m;
865
893
  ${E(c)}
866
894
  animation: none;
867
895
  }`;
868
- const h = ct(n, t, e), g = [
869
- `@keyframes ${h} {`,
896
+ const m = ut(n, t, e), P = [
897
+ `@keyframes ${m} {`,
870
898
  " from {",
871
899
  E(o).replace(/^/gm, " "),
872
900
  " }",
@@ -875,149 +903,149 @@ ${E(c)}
875
903
  " }",
876
904
  "}"
877
905
  ].join(`
878
- `), p = [
879
- `${h}`,
906
+ `), h = [
907
+ `${m}`,
880
908
  `${l}s`,
881
909
  d,
882
910
  u > 0 ? `${u}s` : null,
883
911
  "both"
884
912
  ].filter(Boolean).join(" "), f = Array.from(
885
- /* @__PURE__ */ new Set([...o.map((T) => T.property), ...c.map((T) => T.property)])
913
+ /* @__PURE__ */ new Set([...o.map((N) => N.property), ...c.map((N) => N.property)])
886
914
  ), y = f.length > 0 ? ` will-change: ${f.join(", ")};
887
- ` : "", w = e.split("-")[0], U = `${i} {
888
- animation: ${p};
889
- ${y}${w === "PUSHING" || w === "REPLACING" ? ` contain: layout;
915
+ ` : "", S = e.split("-")[0], Y = `${i} {
916
+ animation: ${h};
917
+ ${y}${S === "PUSHING" || S === "REPLACING" ? ` contain: layout;
890
918
  pointer-events: none;
891
919
  ` : ""}}`;
892
- return `${g}
893
- ${U}`;
894
- }, x = (n, t, e, a) => {
895
- const s = P(a.value);
896
- return s.length === 0 ? "" : `${n(t, e)} {
897
- ${E(s)}
920
+ return `${P}
921
+ ${Y}`;
922
+ }, C = (n, t, e, s) => {
923
+ const a = g(s.value);
924
+ return a.length === 0 ? "" : `${n(t, e)} {
925
+ ${E(a)}
898
926
  }`;
899
- }, wt = (n, t) => {
927
+ }, St = (n, t) => {
900
928
  const e = [];
901
- for (const a of n) {
902
- const s = a.name;
903
- for (const r of G) {
904
- const o = a.variants[r], c = I[r];
929
+ for (const s of n) {
930
+ const a = s.name;
931
+ for (const r of O) {
932
+ const o = s.variants[r], c = k[r];
905
933
  if (c === "self") {
906
- e.push(x(v, s, r, o));
934
+ e.push(C(A, a, r, o));
907
935
  continue;
908
936
  }
909
- const l = c === "initial" ? a.initial : a.variants[c].value;
937
+ const l = c === "initial" ? s.initial : s.variants[c].value;
910
938
  e.push(
911
- M("screen", s, r, l, o, v)
939
+ x("screen", a, r, l, o, A)
912
940
  );
913
941
  }
914
942
  }
915
- for (const a of t) {
916
- const s = a.name;
917
- for (const r of q) {
918
- const o = a.variants[r], c = I[r];
943
+ for (const s of t) {
944
+ const a = s.name;
945
+ for (const r of W) {
946
+ const o = s.variants[r], c = k[r];
919
947
  if (c === "self") {
920
- e.push(x(A, s, r, o));
948
+ e.push(C(M, a, r, o));
921
949
  continue;
922
950
  }
923
- const l = c === "initial" ? a.initial : a.variants[c].value;
951
+ const l = c === "initial" ? s.initial : s.variants[c].value;
924
952
  e.push(
925
- M(
953
+ x(
926
954
  "decorator",
927
- s,
955
+ a,
928
956
  r,
929
957
  l,
930
958
  o,
931
- A
959
+ M
932
960
  )
933
961
  );
934
962
  }
935
963
  }
936
- return e.filter((a) => a.length > 0).join(`
964
+ return e.filter((s) => s.length > 0).join(`
937
965
 
938
966
  `);
939
- }, St = (n, t) => {
940
- const e = I[t];
967
+ }, vt = (n, t) => {
968
+ const e = k[t];
941
969
  if (e === "self") return !1;
942
- const a = n.variants[t], s = _(a.options), r = H(a.options);
943
- if (s <= 0 && r <= 0) return !1;
944
- const o = e === "initial" ? n.initial : n.variants[e].value, c = P(o), l = P(a.value);
970
+ const s = n.variants[t], a = H(s.options), r = U(s.options);
971
+ if (a <= 0 && r <= 0) return !1;
972
+ const o = e === "initial" ? n.initial : n.variants[e].value, c = g(o), l = g(s.value);
945
973
  return c.length > 0 || l.length > 0;
946
974
  };
947
- function vt() {
975
+ function At() {
948
976
  return typeof document > "u";
949
977
  }
950
- function ut(n, t) {
951
- return Array.isArray(n) ? n.find((e) => S(e).regexp.test(t)) ?? "" : S(n).regexp.test(t) ? n : "";
978
+ function lt(n, t) {
979
+ return Array.isArray(n) ? n.find((e) => v(e).regexp.test(t)) ?? "" : v(n).regexp.test(t) ? n : "";
952
980
  }
953
- function At(n, t, e) {
954
- const a = ut(n, t), s = Y(a)(t), r = new URLSearchParams(e), o = Object.fromEntries(r.entries());
955
- return s ? { ...s.params, ...o } : {};
981
+ function Mt(n, t, e) {
982
+ const s = lt(n, t), a = B(s)(t), r = new URLSearchParams(e), o = Object.fromEntries(r.entries());
983
+ return a ? { ...a.params, ...o } : {};
956
984
  }
957
- function Mt(n, t) {
985
+ function xt(n, t) {
958
986
  const {
959
987
  direction: e = "x",
960
- markerSelector: a = "[data-swipe-at-edge]",
961
- depthLimit: s = 24,
988
+ markerSelector: s = "[data-swipe-at-edge]",
989
+ depthLimit: a = 24,
962
990
  verifyByScroll: r = !1
963
- } = t ?? {}, o = lt(n);
991
+ } = t ?? {}, o = ft(n);
964
992
  if (!o) return { element: null, hasMarker: !1 };
965
- const c = o.closest?.(a);
966
- if (c instanceof HTMLElement && L(c, e) && (!r || C(c, e)))
993
+ const c = o.closest?.(s);
994
+ if (c instanceof HTMLElement && D(c, e) && (!r || G(c, e)))
967
995
  return { element: c, hasMarker: !0 };
968
996
  let l = o, u = 0;
969
- for (; l && u < s; ) {
970
- if (L(l, e) && (!r || C(l, e)))
997
+ for (; l && u < a; ) {
998
+ if (D(l, e) && (!r || G(l, e)))
971
999
  return { element: l, hasMarker: !1 };
972
1000
  l = l.parentElement, u++;
973
1001
  }
974
1002
  return { element: null, hasMarker: !1 };
975
1003
  }
976
- function lt(n) {
1004
+ function ft(n) {
977
1005
  if (!n) return null;
978
1006
  const t = n, e = typeof t.composedPath == "function" ? t.composedPath() : void 0;
979
1007
  if (e && e.length) {
980
- for (const a of e)
981
- if (a instanceof HTMLElement) return a;
1008
+ for (const s of e)
1009
+ if (s instanceof HTMLElement) return s;
982
1010
  }
983
1011
  return n instanceof HTMLElement ? n : null;
984
1012
  }
985
- function L(n, t) {
1013
+ function D(n, t) {
986
1014
  return t === "y" ? n.scrollHeight - n.clientHeight > 1 : n.scrollWidth - n.clientWidth > 1;
987
1015
  }
988
- function C(n, t) {
989
- if (!L(n, t) || typeof window > "u") return !1;
990
- const e = window.getComputedStyle(n), a = t === "y" ? e.overflowY : e.overflowX;
991
- return a === "auto" || a === "scroll" || a === "overlay";
1016
+ function G(n, t) {
1017
+ if (!D(n, t) || typeof window > "u") return !1;
1018
+ const e = window.getComputedStyle(n), s = t === "y" ? e.overflowY : e.overflowX;
1019
+ return s === "auto" || s === "scroll" || s === "overlay";
992
1020
  }
993
1021
  export {
994
- pt as TaskManger,
995
- ct as animationName,
996
- C as canProgrammaticallyScroll,
997
- Dt as collectAnimatedProperties,
998
- wt as compileTransitionStyles,
1022
+ yt as TaskManger,
1023
+ ut as animationName,
1024
+ G as canProgrammaticallyScroll,
1025
+ wt as collectAnimatedProperties,
1026
+ St as compileTransitionStyles,
999
1027
  Et as consumeSelfInducedPop,
1000
- j as createDecorator,
1001
- Nt as createRawDecorator,
1002
- It as createRawTransition,
1003
- k as createTransition,
1004
- X as cupertino,
1005
- Lt as decoratorMap,
1006
- ot as easingToCss,
1007
- Mt as findScrollable,
1008
- ut as getMatchedPathPattern,
1009
- At as getParams,
1010
- vt as isServer,
1011
- z as layout,
1012
- Pt as markSelfInducedPop,
1013
- V as material,
1014
- Z as none,
1015
- L as overflowsAxis,
1016
- K as overlay,
1017
- P as targetToDecls,
1018
- kt as transitionMap,
1019
- yt as useHistoryStore,
1028
+ K as createDecorator,
1029
+ Lt as createRawDecorator,
1030
+ kt as createRawTransition,
1031
+ T as createTransition,
1032
+ F as cupertino,
1033
+ Dt as decoratorMap,
1034
+ it as easingToCss,
1035
+ xt as findScrollable,
1036
+ lt as getMatchedPathPattern,
1037
+ Mt as getParams,
1038
+ At as isServer,
1039
+ V as layout,
1040
+ It as markSelfInducedPop,
1041
+ Z as material,
1042
+ j as none,
1043
+ D as overflowsAxis,
1044
+ q as overlay,
1045
+ g as targetToDecls,
1046
+ Tt as transitionMap,
1047
+ Pt as useHistoryStore,
1020
1048
  gt as useNavigateStore,
1021
- Tt as useTransitionStore,
1022
- St as variantHasAnimation
1049
+ Nt as useTransitionStore,
1050
+ vt as variantHasAnimation
1023
1051
  };
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flemo/core",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "Framework-agnostic primitives for flemo: history, navigation, transitions, task manager.",
5
5
  "main": "./dist/index.mjs",
6
6
  "module": "./dist/index.mjs",