@owlmeans/client-planning 0.1.18-rc.9 → 0.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/README.md +94 -11
  2. package/agent-meta/manifest.json +62 -4
  3. package/agent-meta/skills/client-planning/SKILL.md +60 -78
  4. package/agent-meta/skills/client-planning/parts/aux-mirrors.md +61 -0
  5. package/agent-meta/skills/client-planning/parts/mirror.md +67 -0
  6. package/agent-meta/skills/client-planning/parts/validation.md +60 -0
  7. package/build/client.d.ts +1 -1
  8. package/build/client.d.ts.map +1 -1
  9. package/build/client.js +66 -14
  10. package/build/client.js.map +1 -1
  11. package/build/commits.d.ts +2 -13
  12. package/build/commits.d.ts.map +1 -1
  13. package/build/commits.js +190 -132
  14. package/build/commits.js.map +1 -1
  15. package/build/consts.d.ts +4 -0
  16. package/build/consts.d.ts.map +1 -1
  17. package/build/consts.js +10 -4
  18. package/build/consts.js.map +1 -1
  19. package/build/definitions.d.ts +13 -0
  20. package/build/definitions.d.ts.map +1 -0
  21. package/build/definitions.js +70 -0
  22. package/build/definitions.js.map +1 -0
  23. package/build/events/types.d.ts +34 -0
  24. package/build/events/types.d.ts.map +1 -0
  25. package/build/events/types.js +2 -0
  26. package/build/events/types.js.map +1 -0
  27. package/build/events.d.ts +10 -21
  28. package/build/events.d.ts.map +1 -1
  29. package/build/events.js +104 -102
  30. package/build/events.js.map +1 -1
  31. package/build/facade.d.ts.map +1 -1
  32. package/build/facade.js +86 -49
  33. package/build/facade.js.map +1 -1
  34. package/build/feed.d.ts +4 -4
  35. package/build/feed.d.ts.map +1 -1
  36. package/build/feed.js +50 -27
  37. package/build/feed.js.map +1 -1
  38. package/build/helper/types.d.ts +15 -0
  39. package/build/helper/types.d.ts.map +1 -0
  40. package/build/helper/types.js +2 -0
  41. package/build/helper/types.js.map +1 -0
  42. package/build/helper.d.ts +7 -7
  43. package/build/helper.d.ts.map +1 -1
  44. package/build/helper.js +16 -8
  45. package/build/helper.js.map +1 -1
  46. package/build/index.d.ts +11 -0
  47. package/build/index.d.ts.map +1 -1
  48. package/build/index.js +6 -0
  49. package/build/index.js.map +1 -1
  50. package/build/lifecycle/types.d.ts +27 -0
  51. package/build/lifecycle/types.d.ts.map +1 -0
  52. package/build/lifecycle/types.js +2 -0
  53. package/build/lifecycle/types.js.map +1 -0
  54. package/build/lifecycle.d.ts +3 -0
  55. package/build/lifecycle.d.ts.map +1 -0
  56. package/build/lifecycle.js +157 -0
  57. package/build/lifecycle.js.map +1 -0
  58. package/build/resource-feed.d.ts +5 -0
  59. package/build/resource-feed.d.ts.map +1 -0
  60. package/build/resource-feed.js +97 -0
  61. package/build/resource-feed.js.map +1 -0
  62. package/build/resources.d.ts +6 -0
  63. package/build/resources.d.ts.map +1 -0
  64. package/build/resources.js +93 -0
  65. package/build/resources.js.map +1 -0
  66. package/build/stores.d.ts +4 -11
  67. package/build/stores.d.ts.map +1 -1
  68. package/build/stores.js +11 -35
  69. package/build/stores.js.map +1 -1
  70. package/build/sync/types.d.ts +18 -0
  71. package/build/sync/types.d.ts.map +1 -0
  72. package/build/sync/types.js +2 -0
  73. package/build/sync/types.js.map +1 -0
  74. package/build/sync.d.ts +4 -0
  75. package/build/sync.d.ts.map +1 -0
  76. package/build/sync.js +26 -0
  77. package/build/sync.js.map +1 -0
  78. package/build/types.d.ts +48 -3
  79. package/build/types.d.ts.map +1 -1
  80. package/build/types.local.d.ts +13 -0
  81. package/build/types.local.d.ts.map +1 -0
  82. package/build/types.local.js +2 -0
  83. package/build/types.local.js.map +1 -0
  84. package/build/utils/record/types.d.ts +28 -0
  85. package/build/utils/record/types.d.ts.map +1 -0
  86. package/build/utils/record/types.js +2 -0
  87. package/build/utils/record/types.js.map +1 -0
  88. package/build/utils/record.d.ts +3 -24
  89. package/build/utils/record.d.ts.map +1 -1
  90. package/build/utils/record.js +64 -70
  91. package/build/utils/record.js.map +1 -1
  92. package/build/validation/consts.d.ts +23 -0
  93. package/build/validation/consts.d.ts.map +1 -0
  94. package/build/validation/consts.js +289 -0
  95. package/build/validation/consts.js.map +1 -0
  96. package/build/validation/types.d.ts +17 -0
  97. package/build/validation/types.d.ts.map +1 -0
  98. package/build/validation/types.js +2 -0
  99. package/build/validation/types.js.map +1 -0
  100. package/build/validation.d.ts +10 -0
  101. package/build/validation.d.ts.map +1 -0
  102. package/build/validation.js +171 -0
  103. package/build/validation.js.map +1 -0
  104. package/package.json +20 -18
  105. package/src/client.ts +58 -15
  106. package/src/commits.ts +152 -184
  107. package/src/consts.ts +12 -4
  108. package/src/definitions.ts +93 -0
  109. package/src/events/types.ts +35 -0
  110. package/src/events.ts +118 -108
  111. package/src/facade.ts +87 -55
  112. package/src/feed.ts +47 -28
  113. package/src/helper/types.ts +15 -0
  114. package/src/helper.ts +27 -10
  115. package/src/index.ts +12 -0
  116. package/src/lifecycle/types.ts +28 -0
  117. package/src/lifecycle.ts +123 -0
  118. package/src/resource-feed.ts +79 -0
  119. package/src/resources.ts +84 -0
  120. package/src/stores.ts +11 -40
  121. package/src/sync/types.ts +18 -0
  122. package/src/sync.ts +40 -0
  123. package/src/types.local.ts +14 -0
  124. package/src/types.ts +53 -5
  125. package/src/utils/record/types.ts +27 -0
  126. package/src/utils/record.ts +68 -71
  127. package/src/validation/consts.ts +289 -0
  128. package/src/validation/types.ts +18 -0
  129. package/src/validation.ts +140 -0
  130. package/tests/app.spec.ts +72 -0
  131. package/tests/context.ts +46 -15
  132. package/tests/csp.spec.ts +119 -0
  133. package/tests/definitions.spec.ts +74 -0
  134. package/tests/draft7.spec.ts +13 -0
  135. package/tests/events.spec.ts +13 -9
  136. package/tests/facade.spec.ts +2 -1
  137. package/tests/lifecycle/context.ts +29 -0
  138. package/tests/lifecycle-close.spec.ts +103 -0
  139. package/tests/lifecycle-commits.spec.ts +92 -0
  140. package/tests/lifecycle-definitions.spec.ts +28 -0
  141. package/tests/lifecycle-feeds.spec.ts +92 -0
  142. package/tests/lifecycle-sockets.spec.ts +76 -0
  143. package/tests/replies.spec.ts +81 -0
  144. package/tests/resources.spec.ts +116 -0
  145. package/tests/stores.spec.ts +13 -11
  146. package/tests/validation.spec.ts +127 -0
@@ -0,0 +1,27 @@
1
+ /** One captured authenticated generation; cancellation does not undo a server write. */
2
+ export interface PlanningOperation {
3
+ key: string;
4
+ signal: AbortSignal;
5
+ active: () => boolean;
6
+ check: () => void;
7
+ wait: <T>(pending: Promise<T>) => Promise<T>;
8
+ cancel: (reason?: Error) => void;
9
+ release: () => void;
10
+ }
11
+ /** Shared cancellation and the boundary between local mirror mutations and clearing. */
12
+ export interface PlanningClientLifecycle {
13
+ key: () => string;
14
+ capture: (expected?: string) => PlanningOperation;
15
+ run: <T>(work: (operation: PlanningOperation) => Promise<T>) => Promise<T>;
16
+ /** Local store operations only: never hold this queue over an RPC or a socket opener. */
17
+ mutate: <T>(operation: PlanningOperation, work: () => Promise<T>) => Promise<T>;
18
+ drain: () => Promise<void>;
19
+ onInvalidate: (listener: () => void | Promise<void>) => () => void;
20
+ close: () => Promise<void>;
21
+ }
22
+ export interface PlanningClientLifecycleOptions {
23
+ scopeKey?: () => string | undefined;
24
+ /** Runs in the mutation queue after admitted old writes have drained. */
25
+ clear?: () => Promise<void>;
26
+ }
27
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lifecycle/types.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,WAAW,CAAA;IACnB,MAAM,EAAE,MAAM,OAAO,CAAA;IACrB,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IAC5C,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,KAAK,IAAI,CAAA;IAChC,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAED,wFAAwF;AACxF,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,MAAM,MAAM,CAAA;IACjB,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,KAAK,iBAAiB,CAAA;IACjD,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IAC1E,yFAAyF;IACzF,MAAM,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IAC/E,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAA;IAClE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3B;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;IACnC,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lifecycle/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { PlanningClientLifecycle, PlanningClientLifecycleOptions } from './lifecycle/types.js';
2
+ export declare const makePlanningClientLifecycle: (opts?: PlanningClientLifecycleOptions) => PlanningClientLifecycle;
3
+ //# sourceMappingURL=lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,8BAA8B,EAAqB,MAAM,sBAAsB,CAAA;AAItH,eAAO,MAAM,2BAA2B,UAAU,8BAA8B,KAAQ,uBAoHvF,CAAA"}
@@ -0,0 +1,157 @@
1
+ import { logger } from '@owlmeans/log';
2
+ import { PlanningError } from '@owlmeans/planning';
3
+ const log = logger('client-planning');
4
+ export const makePlanningClientLifecycle = (opts = {}) => {
5
+ let identity = opts.scopeKey?.() ?? '';
6
+ let epoch = 0;
7
+ let tail = Promise.resolve();
8
+ let closing = null;
9
+ let blocked = false;
10
+ let failed = false;
11
+ let empty = false;
12
+ let admissions = 0;
13
+ const operations = new Set();
14
+ const listeners = new Set();
15
+ const changed = () => new PlanningError('client:scope-changed');
16
+ const cancel = () => {
17
+ for (const controller of operations)
18
+ controller.abort(changed());
19
+ operations.clear();
20
+ };
21
+ const invalidate = (explicit = true) => {
22
+ // Changing a credential cannot recover a failed clear. Only an awaited explicit retry can.
23
+ if (!explicit && failed) {
24
+ epoch++;
25
+ cancel();
26
+ return Promise.resolve();
27
+ }
28
+ if (explicit && closing != null && blocked)
29
+ return closing;
30
+ // An explicit close rejects admission. A newly observed identity already names the new
31
+ // credential: its RPCs may start, but its local writes queue behind this generation's clear.
32
+ blocked = explicit || blocked;
33
+ epoch++;
34
+ cancel();
35
+ const admitted = admissions;
36
+ const previous = closing;
37
+ let resolve;
38
+ let reject;
39
+ const attempt = new Promise((yes, no) => { resolve = yes; reject = no; });
40
+ closing = attempt;
41
+ // Reserve clearing before invalidation listeners can start work. Each observed identity
42
+ // change reserves its own clear, including changes while an earlier close is still draining.
43
+ const clearing = tail.then(async () => { await opts.clear?.(); }).catch(error => {
44
+ blocked = true;
45
+ failed = true;
46
+ cancel();
47
+ throw error;
48
+ });
49
+ tail = clearing.catch(() => { });
50
+ const stopping = [...listeners].map(async (listener) => { await listener(); });
51
+ void Promise.all([clearing, ...stopping, ...(previous != null ? [previous] : [])]).then(() => {
52
+ if (closing === attempt) {
53
+ blocked = false;
54
+ failed = false;
55
+ closing = null;
56
+ empty = admissions === admitted;
57
+ }
58
+ resolve();
59
+ }, error => {
60
+ if (closing === attempt) {
61
+ blocked = true;
62
+ failed = true;
63
+ closing = null;
64
+ cancel();
65
+ }
66
+ reject(error);
67
+ });
68
+ // key() can invalidate without an awaiting caller; still observe and report cleanup failures.
69
+ void attempt.catch(error => log.error('Planning scope cleanup failed', error));
70
+ return attempt;
71
+ };
72
+ const key = () => {
73
+ const current = opts.scopeKey?.() ?? '';
74
+ if (current !== identity) {
75
+ identity = current;
76
+ // An awaited close already drained and emptied this generation. Adopt the next credential
77
+ // synchronously when no request/feed was admitted since, without a redundant invalidation.
78
+ if (empty && closing == null && !blocked && !failed)
79
+ epoch++;
80
+ else
81
+ void invalidate(false);
82
+ }
83
+ return `${epoch}:${identity}`;
84
+ };
85
+ const capture = (expected) => {
86
+ const captured = key();
87
+ if (blocked)
88
+ throw changed();
89
+ if (expected != null && expected !== captured)
90
+ throw changed();
91
+ empty = false;
92
+ admissions++;
93
+ const controller = new AbortController();
94
+ operations.add(controller);
95
+ const active = () => key() === captured && !blocked && !controller.signal.aborted;
96
+ const check = () => {
97
+ if (key() !== captured || blocked)
98
+ throw changed();
99
+ if (controller.signal.aborted)
100
+ throw controller.signal.reason;
101
+ };
102
+ const wait = async (pending) => {
103
+ let abort;
104
+ try {
105
+ // Observe even an already-cancelled operation's pending promise; a late RPC rejection
106
+ // must never become unhandled after its caller has left this generation.
107
+ const cancelled = new Promise((_, reject) => {
108
+ abort = () => reject(controller.signal.reason ?? changed());
109
+ controller.signal.addEventListener('abort', abort, { once: true });
110
+ if (!active())
111
+ abort();
112
+ });
113
+ const result = await Promise.race([pending, cancelled]);
114
+ check();
115
+ return result;
116
+ }
117
+ catch (error) {
118
+ check();
119
+ throw error;
120
+ }
121
+ finally {
122
+ if (abort != null)
123
+ controller.signal.removeEventListener('abort', abort);
124
+ }
125
+ };
126
+ return { key: captured, signal: controller.signal, active, check, wait,
127
+ cancel: reason => { controller.abort(reason ?? changed()); }, release: () => { operations.delete(controller); } };
128
+ };
129
+ return {
130
+ key, capture,
131
+ run: async (work) => {
132
+ const operation = capture();
133
+ try {
134
+ const result = await work(operation);
135
+ operation.check();
136
+ return result;
137
+ }
138
+ finally {
139
+ operation.release();
140
+ }
141
+ },
142
+ mutate: async (operation, work) => {
143
+ const writing = tail.then(async () => {
144
+ operation.check();
145
+ const result = await work();
146
+ operation.check();
147
+ return result;
148
+ });
149
+ tail = writing.then(() => { }, () => { });
150
+ return await writing;
151
+ },
152
+ drain: async () => { await tail; },
153
+ onInvalidate: listener => { listeners.add(listener); return () => { listeners.delete(listener); }; },
154
+ close: async () => { identity = opts.scopeKey?.() ?? ''; await invalidate(); },
155
+ };
156
+ };
157
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { BasicConfig, BasicContext } from '@owlmeans/context';
2
+ import type { PlanningFeed, PlanningResourceFeedOptions } from './types.js';
3
+ /** Refresh separate resources into the stock stores; a stopped/changed-tenant feed cannot publish. */
4
+ export declare const makePlanningResourceFeed: <C extends BasicConfig, T extends BasicContext<C>>(context: T, opts?: PlanningResourceFeedOptions) => PlanningFeed;
5
+ //# sourceMappingURL=resource-feed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-feed.d.ts","sourceRoot":"","sources":["../src/resource-feed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAIlE,OAAO,KAAK,EAAyB,YAAY,EAAqB,2BAA2B,EAAE,MAAM,YAAY,CAAA;AAErH,sGAAsG;AACtG,eAAO,MAAM,wBAAwB,GAAI,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,WAC9E,CAAC,SAAQ,2BAA2B,KAC5C,YAqEF,CAAA"}
@@ -0,0 +1,97 @@
1
+ import { mentionHelper, PLANNING_SERVICE } from '@owlmeans/planning';
2
+ import { planningContextOf } from './helper.js';
3
+ /** Refresh separate resources into the stock stores; a stopped/changed-tenant feed cannot publish. */
4
+ export const makePlanningResourceFeed = (context, opts = {}) => {
5
+ const stores = planningContextOf(context).stores();
6
+ if (stores == null)
7
+ throw new SyntaxError('Planning feed needs appendPlanningStores(context)');
8
+ const service = context.service(PLANNING_SERVICE);
9
+ const { lifecycle } = service;
10
+ const operation = lifecycle.capture();
11
+ const active = () => !stopped && operation.active();
12
+ const facade = service.for(opts.scope);
13
+ const state = { connected: false, seeded: false, error: null };
14
+ let stopped = false;
15
+ let pending;
16
+ let timer;
17
+ const refresh = async () => {
18
+ if (!active())
19
+ return;
20
+ if (pending != null)
21
+ return await pending;
22
+ pending = (async () => {
23
+ try {
24
+ for (const name of ['assignees', 'teams', 'comments', 'mentions']) {
25
+ const query = opts[name];
26
+ if (query == null)
27
+ continue;
28
+ const store = stores[name];
29
+ const { page: _page, size: _size, sort: _sort, ids, nickname, authentication, ...where } = query;
30
+ const matches = { ...where, ...(ids != null ? { id: { $in: ids } } : {}),
31
+ ...(name === 'assignees' && where.retired === false ? { retired: { $ne: true } } : {}),
32
+ ...(nickname != null ? { nicknameKey: mentionHelper.nicknameKey(nickname) } : {}),
33
+ ...(authentication != null ? { 'authentication.provider': authentication.provider, 'authentication.externalId': authentication.externalId } : {}),
34
+ ...(opts.scope?.entityId != null ? { entityId: opts.scope.entityId } : {}) };
35
+ // Capture prior versions before the request: a local mutation/new row arriving while
36
+ // the seed is in flight must survive an older snapshot's absence.
37
+ const snapshot = (await operation.wait(store.list(matches, { size: 0 }))).items;
38
+ operation.check();
39
+ const rows = await operation.wait(facade[name].list(query));
40
+ if (!active())
41
+ return;
42
+ const named = new Set(rows.items.map(row => row.id));
43
+ await lifecycle.mutate(operation, async () => {
44
+ if (!(query.size != null && query.size > 0)) {
45
+ for (const row of snapshot)
46
+ if (!named.has(row.id)) {
47
+ const current = await store.load(row.id);
48
+ if (current?.version === row.version)
49
+ await store.delete(row.id);
50
+ }
51
+ }
52
+ for (const row of rows.items) {
53
+ const previous = await store.load(row.id);
54
+ if (previous == null || previous.version <= row.version)
55
+ await store.save(row);
56
+ }
57
+ });
58
+ }
59
+ if (active())
60
+ Object.assign(state, { seeded: true, error: null });
61
+ }
62
+ catch (error) {
63
+ if (active())
64
+ state.error = error;
65
+ }
66
+ if (active())
67
+ opts.onChange?.({ ...state });
68
+ })();
69
+ try {
70
+ await pending;
71
+ }
72
+ finally {
73
+ pending = undefined;
74
+ }
75
+ };
76
+ const ready = refresh().then(() => {
77
+ if (active() && (opts.refresh ?? 5000) > 0)
78
+ timer = setInterval(() => { void refresh(); }, opts.refresh ?? 5000);
79
+ });
80
+ let unregister;
81
+ const feed = {
82
+ get connected() { return state.connected; }, get seeded() { return state.seeded; }, get error() { return state.error; },
83
+ ready, refresh,
84
+ stop: async () => {
85
+ stopped = true;
86
+ operation.cancel();
87
+ unregister?.();
88
+ if (timer != null)
89
+ clearInterval(timer);
90
+ await lifecycle.drain();
91
+ operation.release();
92
+ },
93
+ };
94
+ unregister = service.registerFeed(feed);
95
+ return feed;
96
+ };
97
+ //# sourceMappingURL=resource-feed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-feed.js","sourceRoot":"","sources":["../src/resource-feed.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { BasicContext, BasicConfig } from '@owlmeans/context';
2
+ import type { PlanningProtocols, PlanningResourceFacade } from '@owlmeans/planning';
3
+ import type { RemoteFacadeOptions } from './types.js';
4
+ /** The same auxiliary facade in browsers and Node clients, with versioned stock state mirrors. */
5
+ export declare const makeRemoteResourceFacade: <C extends BasicConfig, T extends BasicContext<C>>(context: T, protocols: PlanningProtocols, opts: RemoteFacadeOptions) => PlanningResourceFacade;
6
+ //# sourceMappingURL=resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAElE,OAAO,KAAK,EAAsE,iBAAiB,EAA2B,sBAAsB,EAAyC,MAAM,oBAAoB,CAAA;AACvN,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAIrD,kGAAkG;AAClG,eAAO,MAAM,wBAAwB,GAAI,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,WAC9E,CAAC,aAAa,iBAAiB,QAAQ,mBAAmB,KAClE,sBAyEF,CAAA"}
@@ -0,0 +1,93 @@
1
+ import { planningReplyHelper, PlanningUnsupported, WorkcardNotFound } from '@owlmeans/planning';
2
+ import { makePlanningClientLifecycle } from './lifecycle.js';
3
+ /** The same auxiliary facade in browsers and Node clients, with versioned stock state mirrors. */
4
+ export const makeRemoteResourceFacade = (context, protocols, opts) => {
5
+ const lifecycle = opts.lifecycle ?? makePlanningClientLifecycle({ scopeKey: opts.scopeKey });
6
+ const tree = (name) => {
7
+ const value = protocols[name];
8
+ if (value == null)
9
+ throw new PlanningUnsupported(`client:${name}`);
10
+ return value;
11
+ };
12
+ const mirror = async (name, row) => {
13
+ const store = opts.stores?.()?.[name];
14
+ if (store == null || row.id == null)
15
+ return;
16
+ const known = await store.load(row.id);
17
+ if (known == null || known.version <= row.version)
18
+ await store.save(row);
19
+ };
20
+ const get = async (name, id) => lifecycle.run(async (operation) => {
21
+ const row = planningReplyHelper.hydrate(await operation.wait(context.entrypoint(tree(name).get).call({ params: { id }, timeout: opts.timeout, signal: operation.signal })));
22
+ await lifecycle.mutate(operation, async () => await mirror(name, row));
23
+ return row;
24
+ });
25
+ const load = async (name, id) => {
26
+ try {
27
+ return await get(name, id);
28
+ }
29
+ catch (error) {
30
+ if (error instanceof WorkcardNotFound)
31
+ return null;
32
+ throw error;
33
+ }
34
+ };
35
+ const list = async (name, query) => lifecycle.run(async (operation) => {
36
+ const rows = planningReplyHelper.hydrate(await operation.wait(context.entrypoint(tree(name).list).call({ query: { query: JSON.stringify(query ?? {}) }, timeout: opts.timeout, signal: operation.signal })));
37
+ return rows;
38
+ });
39
+ const write = async (name, body) => lifecycle.run(async (operation) => {
40
+ const answer = planningReplyHelper.hydrate(await operation.wait(context.entrypoint(tree(name).write).call({ body, timeout: opts.timeout, signal: operation.signal })));
41
+ await lifecycle.mutate(operation, async () => {
42
+ if (answer != null && !Array.isArray(answer))
43
+ await mirror(name, answer);
44
+ if (name === 'mentions' && Array.isArray(answer))
45
+ for (const row of answer)
46
+ if (typeof row !== 'string')
47
+ await mirror(name, row);
48
+ if (body.action === 'remove' && body.id != null)
49
+ await opts.stores?.()?.[name].delete(body.id);
50
+ });
51
+ return answer;
52
+ });
53
+ return {
54
+ assignees: {
55
+ get: async (id) => await get('assignees', id),
56
+ load: async (id) => await load('assignees', id),
57
+ list: async (query) => await list('assignees', query),
58
+ create: async (draft) => await write('assignees', { action: 'create', draft }),
59
+ update: async (id, draft, options) => await write('assignees', { action: 'update', id, draft, ...options }),
60
+ retire: async (id, options) => await write('assignees', { action: 'retire', id, ...options }),
61
+ },
62
+ teams: {
63
+ get: async (id) => await get('teams', id),
64
+ load: async (id) => await load('teams', id),
65
+ list: async (query) => await list('teams', query),
66
+ create: async (draft) => await write('teams', { action: 'create', draft }),
67
+ update: async (id, draft, options) => await write('teams', { action: 'update', id, draft, ...options }),
68
+ remove: async (id, options) => { await write('teams', { action: 'remove', id, ...options }); },
69
+ members: async (id) => await write('teams', { action: 'members', id }),
70
+ projects: async (id) => await write('teams', { action: 'projects', id }),
71
+ assignees: async (id) => await write('teams', { action: 'assignees', id }),
72
+ addMember: async (id, assignee) => { await write('teams', { action: 'addMember', id, assignee }); },
73
+ removeMember: async (id, assignee) => { await write('teams', { action: 'removeMember', id, assignee }); },
74
+ attach: async (id, project) => { await write('teams', { action: 'attach', id, project }); },
75
+ detach: async (id, project) => { await write('teams', { action: 'detach', id, project }); },
76
+ },
77
+ comments: {
78
+ get: async (id) => await get('comments', id),
79
+ load: async (id) => await load('comments', id),
80
+ list: async (query) => await list('comments', query),
81
+ create: async (draft) => await write('comments', { action: 'create', draft }),
82
+ update: async (id, draft, options) => await write('comments', { action: 'update', id, draft, ...options }),
83
+ remove: async (id, options) => { await write('comments', { action: 'remove', id, ...options }); },
84
+ },
85
+ mentions: {
86
+ get: async (id) => await get('mentions', id),
87
+ load: async (id) => await load('mentions', id),
88
+ list: async (query) => await list('mentions', query),
89
+ rebuild: async (id) => await write('mentions', { action: 'rebuild', id }),
90
+ },
91
+ };
92
+ };
93
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"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"}
package/build/stores.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { BasicConfig, BasicContext } from '@owlmeans/context';
2
2
  import type { Relationship, Workcard } from '@owlmeans/planning';
3
3
  import type { Criteria } from '@owlmeans/resource';
4
- import type { StateResourceAppend } from '@owlmeans/state';
4
+ import { type StateResourceAppend } from '@owlmeans/state';
5
5
  import type { PlanningStoreAliases, PlanningStores, SyncOptions, WithPlanningStores } from './types.js';
6
6
  /**
7
7
  * Register the planning state mirror: ONE card store for every kind, a link store and a commit
@@ -12,17 +12,10 @@ import type { PlanningStoreAliases, PlanningStores, SyncOptions, WithPlanningSto
12
12
  * homes the moment its kind is read wrong. Idempotent, like every `append*`.
13
13
  */
14
14
  export declare const appendPlanningStores: <C extends BasicConfig, T extends BasicContext<C>>(context: T, aliases?: Partial<PlanningStoreAliases>) => T & WithPlanningStores & StateResourceAppend;
15
- /** The stores `appendPlanningStores` registered, or `null` on a context that has none. */
15
+ /** @deprecated compat:factory-refactor — use `planningContextOf(context).stores()` */
16
16
  export declare const planningStoresOf: (context: BasicContext<any>) => PlanningStores | null;
17
- /**
18
- * Make the store agree with an authoritative list WITHIN a scope: every card given is written
19
- * (unless the store holds a newer fold of it), and every card matching `where` that the list does
20
- * not name is dropped. Cards outside `where` are left alone — which is why this, and never
21
- * `replace()`, is how a list reaches the one shared card store.
22
- *
23
- * Unchanged cards are not rewritten, so a periodic re-seed wakes no subscriber.
24
- */
17
+ /** @deprecated compat:factory-refactor — use `syncHelper.syncCards(…)` */
25
18
  export declare const syncCards: (store: PlanningStores['cards'], items: Workcard[], where?: Criteria<Workcard>, opts?: SyncOptions) => Promise<void>;
26
- /** {@link syncCards} for the link store. */
19
+ /** @deprecated compat:factory-refactor — use `syncHelper.syncLinks(…)` */
27
20
  export declare const syncLinks: (store: PlanningStores['links'], items: Relationship[], where?: Criteria<Relationship>, opts?: SyncOptions) => Promise<void>;
28
21
  //# sourceMappingURL=stores.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stores.d.ts","sourceRoot":"","sources":["../src/stores.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAElD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAE1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAGvG;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,WAC1E,CAAC,YAAY,OAAO,CAAC,oBAAoB,CAAC,KAClD,CAAC,GAAG,kBAAkB,GAAG,mBAgB3B,CAAA;AAED,0FAA0F;AAC1F,eAAO,MAAM,gBAAgB,YAAa,YAAY,CAAC,GAAG,CAAC,KAAG,cAAc,GAAG,IAI9E,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,UACb,cAAc,CAAC,OAAO,CAAC,SAAS,QAAQ,EAAE,UAAU,QAAQ,CAAC,QAAQ,CAAC,SAAS,WAAW,KAChG,OAAO,CAAC,IAAI,CAKd,CAAA;AAED,4CAA4C;AAC5C,eAAO,MAAM,SAAS,UACb,cAAc,CAAC,OAAO,CAAC,SAAS,YAAY,EAAE,UAAU,QAAQ,CAAC,YAAY,CAAC,SAAS,WAAW,KACxG,OAAO,CAAC,IAAI,CAKd,CAAA"}
1
+ {"version":3,"file":"stores.d.ts","sourceRoot":"","sources":["../src/stores.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAuB,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAI/E,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEvG;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,WAC1E,CAAC,YAAY,OAAO,CAAC,oBAAoB,CAAC,KAClD,CAAC,GAAG,kBAAkB,GAAG,mBAkB3B,CAAA;AAGD,sFAAsF;AACtF,eAAO,MAAM,gBAAgB,YAAa,YAAY,CAAC,GAAG,CAAC,KAAG,cAAc,GAAG,IAA2C,CAAA;AAE1H,0EAA0E;AAC1E,eAAO,MAAM,SAAS,UACb,cAAc,CAAC,OAAO,CAAC,SAAS,QAAQ,EAAE,UAAU,QAAQ,CAAC,QAAQ,CAAC,SAAS,WAAW,KAChG,OAAO,CAAC,IAAI,CAA0D,CAAA;AAEzE,0EAA0E;AAC1E,eAAO,MAAM,SAAS,UACb,cAAc,CAAC,OAAO,CAAC,SAAS,YAAY,EAAE,UAAU,QAAQ,CAAC,YAAY,CAAC,SAAS,WAAW,KACxG,OAAO,CAAC,IAAI,CAA0D,CAAA"}
package/build/stores.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { appendStateResource } from '@owlmeans/state';
2
2
  import { DEFAULT_STORE_ALIASES } from './consts.js';
3
- import { idsOf, putCard, putLink } from './utils/record.js';
3
+ import { planningContextOf } from './helper.js';
4
+ import { syncHelper } from './sync.js';
4
5
  /**
5
6
  * Register the planning state mirror: ONE card store for every kind, a link store and a commit
6
7
  * store, and `context.planningStores()`.
@@ -14,48 +15,23 @@ export const appendPlanningStores = (context, aliases) => {
14
15
  let ctx = appendStateResource(context, names.cards);
15
16
  ctx = appendStateResource(ctx, names.links);
16
17
  ctx = appendStateResource(ctx, names.commits);
18
+ for (const name of [names.assignees, names.teams, names.comments, names.mentions])
19
+ ctx = appendStateResource(ctx, name);
17
20
  const result = ctx;
18
21
  if (result.planningStores == null) {
19
22
  result.planningStores = () => ({
20
23
  cards: result.getStateResource(names.cards),
24
+ assignees: result.getStateResource(names.assignees), teams: result.getStateResource(names.teams), comments: result.getStateResource(names.comments), mentions: result.getStateResource(names.mentions),
21
25
  links: result.getStateResource(names.links),
22
26
  commits: result.getStateResource(names.commits),
23
27
  });
24
28
  }
25
29
  return result;
26
30
  };
27
- /** The stores `appendPlanningStores` registered, or `null` on a context that has none. */
28
- export const planningStoresOf = (context) => {
29
- const ctx = context;
30
- return typeof ctx.planningStores === 'function' ? ctx.planningStores() : null;
31
- };
32
- /**
33
- * Make the store agree with an authoritative list WITHIN a scope: every card given is written
34
- * (unless the store holds a newer fold of it), and every card matching `where` that the list does
35
- * not name is dropped. Cards outside `where` are left alone — which is why this, and never
36
- * `replace()`, is how a list reaches the one shared card store.
37
- *
38
- * Unchanged cards are not rewritten, so a periodic re-seed wakes no subscriber.
39
- */
40
- export const syncCards = async (store, items, where, opts) => {
41
- await dropUnnamed(store, idsOf(items), where, opts);
42
- for (const item of items) {
43
- await putCard(store, item);
44
- }
45
- };
46
- /** {@link syncCards} for the link store. */
47
- export const syncLinks = async (store, items, where, opts) => {
48
- await dropUnnamed(store, idsOf(items), where, opts);
49
- for (const item of items) {
50
- await putLink(store, item);
51
- }
52
- };
53
- const dropUnnamed = async (store, named, where, opts) => {
54
- const keep = new Set([...named, ...(opts?.keep ?? [])]);
55
- const scoped = await store.list(where);
56
- const stale = idsOf(scoped.items).filter(id => !keep.has(id));
57
- if (stale.length > 0) {
58
- await store.purge({ id: { $in: stale } });
59
- }
60
- };
31
+ /** @deprecated compat:factory-refactor — use `planningContextOf(context).stores()` */
32
+ export const planningStoresOf = (context) => planningContextOf(context).stores();
33
+ /** @deprecated compat:factory-refactor — use `syncHelper.syncCards(…)` */
34
+ export const syncCards = async (store, items, where, opts) => await syncHelper.syncCards(store, items, where, opts);
35
+ /** @deprecated compat:factory-refactor — use `syncHelper.syncLinks(…)` */
36
+ export const syncLinks = async (store, items, where, opts) => await syncHelper.syncLinks(store, items, where, opts);
61
37
  //# sourceMappingURL=stores.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stores.js","sourceRoot":"","sources":["../src/stores.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stores.js","sourceRoot":"","sources":["../src/stores.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAA4B,MAAM,iBAAiB,CAAA;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAGtC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,OAAU,EAAE,OAAuC,EACL,EAAE;IAChD,MAAM,KAAK,GAAyB,EAAE,GAAG,qBAAqB,EAAE,GAAG,OAAO,EAAE,CAAA;IAC5E,IAAI,GAAG,GAAG,mBAAmB,CAAiB,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IACnE,GAAG,GAAG,mBAAmB,CAA8B,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IACxE,GAAG,GAAG,mBAAmB,CAAgB,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;IAE5D,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC;QAAE,GAAG,GAAG,mBAAmB,CAAC,GAAG,EAAE,IAAW,CAAC,CAAA;IAC9H,MAAM,MAAM,GAAG,GAAmD,CAAA;IAClE,IAAI,MAAM,CAAC,cAAc,IAAI,IAAI,EAAE,CAAC;QAClC,MAAM,CAAC,cAAc,GAAG,GAAG,EAAE,CAAC,CAAC;YAC7B,KAAK,EAAE,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC;YAC3C,SAAS,EAAE,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC;YACtM,KAAK,EAAE,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC;YAC3C,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC;SAChD,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAGD,sFAAsF;AACtF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAA0B,EAAyB,EAAE,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAA;AAE1H,0EAA0E;AAC1E,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC5B,KAA8B,EAAE,KAAiB,EAAE,KAA0B,EAAE,IAAkB,EAClF,EAAE,CAAC,MAAM,UAAU,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;AAEzE,0EAA0E;AAC1E,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC5B,KAA8B,EAAE,KAAqB,EAAE,KAA8B,EAAE,IAAkB,EAC1F,EAAE,CAAC,MAAM,UAAU,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA"}
@@ -0,0 +1,18 @@
1
+ import type { Relationship, Workcard } from '@owlmeans/planning';
2
+ import type { Criteria } from '@owlmeans/resource';
3
+ import type { PlanningStores, SyncOptions } from '../types.js';
4
+ /** An authoritative list made true in one mirror store — within a scope, never beyond it. */
5
+ export interface SyncHelper {
6
+ /**
7
+ * Make the store agree with an authoritative list WITHIN a scope: every card given is written
8
+ * (unless the store holds a newer fold of it), and every card matching `where` that the list does
9
+ * not name is dropped. Cards outside `where` are left alone — which is why this, and never
10
+ * `replace()`, is how a list reaches the one shared card store.
11
+ *
12
+ * Unchanged cards are not rewritten, so a periodic re-seed wakes no subscriber.
13
+ */
14
+ syncCards: (store: PlanningStores['cards'], items: Workcard[], where?: Criteria<Workcard>, opts?: SyncOptions) => Promise<void>;
15
+ /** {@link SyncHelper.syncCards} for the link store. */
16
+ syncLinks: (store: PlanningStores['links'], items: Relationship[], where?: Criteria<Relationship>, opts?: SyncOptions) => Promise<void>;
17
+ }
18
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sync/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9D,6FAA6F;AAC7F,MAAM,WAAW,UAAU;IACzB;;;;;;;OAOG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/H,uDAAuD;IACvD,SAAS,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACxI"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sync/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { SyncHelper } from './sync/types.js';
2
+ export declare const createSyncHelper: () => SyncHelper;
3
+ export declare const syncHelper: SyncHelper;
4
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAIjD,eAAO,MAAM,gBAAgB,QAAO,UA+BnC,CAAA;AAED,eAAO,MAAM,UAAU,YAAqB,CAAA"}