mnfst 0.5.188 → 0.5.190

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 (58) hide show
  1. package/lib/manifest.accordion.css +3 -1
  2. package/lib/manifest.appwrite.auth.js +7 -1
  3. package/lib/manifest.appwrite.data.js +8 -1
  4. package/lib/manifest.avatar.css +6 -4
  5. package/lib/manifest.button.css +7 -5
  6. package/lib/manifest.chart.css +2 -0
  7. package/lib/manifest.chat.js +7 -0
  8. package/lib/manifest.checkbox.css +6 -4
  9. package/lib/manifest.code.css +3 -1
  10. package/lib/manifest.code.js +6 -0
  11. package/lib/manifest.code.min.css +1 -1
  12. package/lib/manifest.colorpicker.css +7 -5
  13. package/lib/manifest.colorpicker.js +3 -0
  14. package/lib/manifest.combobox.css +14 -2
  15. package/lib/manifest.combobox.js +24 -5
  16. package/lib/manifest.components.js +7 -1
  17. package/lib/manifest.css +133 -67
  18. package/lib/manifest.d.ts +214 -30
  19. package/lib/manifest.data.js +71 -29
  20. package/lib/manifest.datepicker.css +15 -13
  21. package/lib/manifest.dialog.css +2 -0
  22. package/lib/manifest.divider.css +3 -1
  23. package/lib/manifest.dropdown.css +6 -4
  24. package/lib/manifest.dropdowns.js +25 -2
  25. package/lib/manifest.export.js +6 -0
  26. package/lib/manifest.form.css +3 -1
  27. package/lib/manifest.input.css +7 -5
  28. package/lib/manifest.integrity.json +25 -25
  29. package/lib/manifest.js +39 -0
  30. package/lib/manifest.localization.js +6 -1
  31. package/lib/manifest.markdown.js +24 -1
  32. package/lib/manifest.min.css +1 -1
  33. package/lib/manifest.native.js +7 -0
  34. package/lib/manifest.payments.js +7 -0
  35. package/lib/manifest.radio.css +2 -0
  36. package/lib/manifest.range.css +6 -4
  37. package/lib/manifest.resize.css +3 -1
  38. package/lib/manifest.resize.js +6 -1
  39. package/lib/manifest.router.js +7 -0
  40. package/lib/manifest.schema.json +29 -0
  41. package/lib/manifest.sidebar.css +2 -0
  42. package/lib/manifest.slides.css +2 -0
  43. package/lib/manifest.status.js +7 -0
  44. package/lib/manifest.svg.js +6 -0
  45. package/lib/manifest.switch.css +5 -3
  46. package/lib/manifest.table.css +4 -2
  47. package/lib/manifest.tabs.js +6 -1
  48. package/lib/manifest.theme.css +4 -2
  49. package/lib/manifest.toast.css +4 -2
  50. package/lib/manifest.toasts.js +6 -1
  51. package/lib/manifest.tooltip.css +2 -0
  52. package/lib/manifest.tooltips.js +6 -0
  53. package/lib/manifest.typography.css +5 -3
  54. package/lib/manifest.url.parameters.js +6 -0
  55. package/lib/manifest.utilities.css +7 -5
  56. package/lib/manifest.utilities.js +20 -1
  57. package/lib/manifest.virtual.js +6 -0
  58. package/package.json +5 -5
package/lib/manifest.d.ts CHANGED
@@ -139,41 +139,49 @@ export interface ManifestLocale {
139
139
  set(locale: string): void;
140
140
  }
141
141
 
142
- /** `$toast` from the toasts plugin. */
143
- export interface ManifestToast {
144
- (message: string, opts?: { type?: 'info' | 'success' | 'warning' | 'error'; duration?: number }): void;
145
- info(message: string, opts?: Record<string, unknown>): void;
146
- success(message: string, opts?: Record<string, unknown>): void;
147
- warning(message: string, opts?: Record<string, unknown>): void;
148
- error(message: string, opts?: Record<string, unknown>): void;
149
- dismiss(id?: string): void;
142
+ /** One toast flavor: callable, with `.dismiss` (adds a close button) and `.fixed` (sticky) variants. */
143
+ export interface ManifestToastVariant {
144
+ (message: string, opts?: Record<string, unknown>): void;
145
+ dismiss(message: string, opts?: Record<string, unknown>): void;
146
+ fixed(message: string, opts?: Record<string, unknown>): void;
150
147
  }
151
148
 
152
- /** `$colors` from the themes plugin. */
153
- export interface ManifestTheme {
154
- readonly current: 'light' | 'dark' | 'system';
155
- set(theme: 'light' | 'dark' | 'system'): void;
156
- toggle(): void;
149
+ /** `$toast` from the toasts plugin. Typed variants: `$toast.brand(...)`, `$toast.positive.dismiss(...)`. */
150
+ export interface ManifestToast extends ManifestToastVariant {
151
+ brand: ManifestToastVariant;
152
+ accent: ManifestToastVariant;
153
+ positive: ManifestToastVariant;
154
+ negative: ManifestToastVariant;
157
155
  }
158
156
 
159
- /** `$colors` from the colors plugin. */
160
- export interface ManifestColors {
161
- [name: string]: string | ManifestColors;
157
+ /** `$color` from the color plugin — the current light/dark/system color mode. */
158
+ export interface ManifestColor {
159
+ current: 'light' | 'dark' | 'system' | string;
162
160
  }
163
161
 
164
- /** `$colorpicker` from the colorpicker plugin. */
162
+ /** `$colorpicker` from the colorpicker plugin. Loose by design. */
165
163
  export interface ManifestColorpicker {
166
- open(opts?: Record<string, unknown>): void;
167
- close(): void;
164
+ (id?: string): Record<string, unknown>;
168
165
  [extra: string]: unknown;
169
166
  }
170
167
 
171
- /** `$url` from the url-parameters plugin: read/write URL query params reactively. */
168
+ /** One URL query parameter handle from `$url.<name>` (reactive). */
169
+ export interface ManifestUrlParam {
170
+ /** Current value (get/set; empty string when absent). */
171
+ value: string;
172
+ /** First value when the param repeats. */
173
+ readonly first: string;
174
+ /** All values for a repeating param. */
175
+ readonly all: string[];
176
+ set(value: string): void;
177
+ add(value: string): void;
178
+ remove(value?: string): void;
179
+ clear(): void;
180
+ }
181
+
182
+ /** `$url` from the url-parameters plugin: `$url.tab.value`, `$url.tag.add('x')`, ... */
172
183
  export interface ManifestUrl {
173
- get(name: string): string | null;
174
- set(name: string, value: string | null): void;
175
- has(name: string): boolean;
176
- [name: string]: unknown;
184
+ [param: string]: ManifestUrlParam;
177
185
  }
178
186
 
179
187
  /** `$route` magic — true if the current route matches the given pattern. */
@@ -188,6 +196,152 @@ export type ManifestModify = (attr: string) => string | undefined;
188
196
  /** `$try(fn)` — run a callback and swallow any thrown error, returning undefined on failure. */
189
197
  export type ManifestTry = <T>(fn: () => T) => T | undefined;
190
198
 
199
+ /** `$pay` from the payments plugin: callable to start checkout, plus portal/state helpers. */
200
+ export interface ManifestPay {
201
+ (ref: string, payload?: Record<string, unknown>): Promise<unknown>;
202
+ portal(ref?: string, payload?: Record<string, unknown>): Promise<unknown>;
203
+ refresh(): Promise<unknown>;
204
+ register(name: string, adapter: unknown): void;
205
+ readonly state: Record<string, unknown> | undefined;
206
+ readonly loading: boolean | undefined;
207
+ [extra: string]: unknown;
208
+ }
209
+
210
+ /** A conversation handle returned by `$chat.open(...)`. Loose by design. */
211
+ export interface ManifestChatHandle {
212
+ readonly messages: unknown[];
213
+ readonly participants: unknown[];
214
+ readonly typing: unknown[];
215
+ readonly me: unknown;
216
+ [extra: string]: unknown;
217
+ }
218
+
219
+ /** `$chat` from the chat plugin — adapter-based conversation projection. */
220
+ export interface ManifestChat {
221
+ open(conversationId: string, opts?: Record<string, unknown>): ManifestChatHandle;
222
+ merge(handles: ManifestChatHandle[], opts?: Record<string, unknown>): ManifestChatHandle;
223
+ adapter(name: string, factory?: unknown): unknown;
224
+ flatten(tree: unknown): unknown[];
225
+ /** Shared revision counter — trackable even before any handle resolves. */
226
+ readonly version: number;
227
+ [extra: string]: unknown;
228
+ }
229
+
230
+ /** One `$status.<name>` entry. */
231
+ export interface ManifestStatusEntry {
232
+ readonly state: string;
233
+ [extra: string]: unknown;
234
+ }
235
+
236
+ /** `$status` from the status plugin: `$status.api.state`, iterable, stringifies to the overall state. */
237
+ export interface ManifestStatus extends Iterable<ManifestStatusEntry> {
238
+ readonly [name: string]: any;
239
+ }
240
+
241
+ /** `$presence` from the Appwrite presences plugin. */
242
+ export interface ManifestPresence {
243
+ start(opts?: Record<string, unknown>): Promise<unknown>;
244
+ stop(): void;
245
+ set(values: Record<string, unknown>): Promise<unknown>;
246
+ clear(): Promise<unknown>;
247
+ of(userId: string): unknown;
248
+ all(): unknown[];
249
+ readonly records: Record<string, unknown>;
250
+ readonly list: unknown[];
251
+ readonly ready: boolean;
252
+ readonly error: unknown;
253
+ readonly me: unknown;
254
+ }
255
+
256
+ /** `$date(id?)` from the datepicker plugin — the picker API for the nearest (or given) instance. */
257
+ export type ManifestDate = (id?: string) => Record<string, unknown>;
258
+
259
+ /** `$chart(id?)` from the charts plugin — the chart API for the nearest (or given) instance. */
260
+ export type ManifestChart = (id?: string) => Record<string, unknown>;
261
+
262
+ /** `$export(opts)` from the export plugin — export the page or a data source (pdf/csv/json/...). */
263
+ export type ManifestExport = (opts?: {
264
+ format?: string;
265
+ filename?: string;
266
+ source?: string;
267
+ data?: unknown;
268
+ [extra: string]: unknown;
269
+ }) => Promise<unknown>;
270
+
271
+ /** `$device` from the utilities plugin (enriched by the native plugin when present). */
272
+ export interface ManifestDevice {
273
+ readonly os: string;
274
+ readonly touch: boolean;
275
+ readonly online: boolean;
276
+ readonly standalone: boolean;
277
+ readonly native: boolean;
278
+ readonly platform: string;
279
+ }
280
+
281
+ /** `$share` from the native plugin — native sheet, web share, or clipboard fallback. */
282
+ export type ManifestShare = (opts?: { title?: string; text?: string; url?: string }) =>
283
+ Promise<{ shared: boolean; method: string; cancelled?: boolean }>;
284
+
285
+ /** `$push` from the native plugin — push/notification permissions and token. */
286
+ export interface ManifestPush {
287
+ request(): Promise<string>;
288
+ readonly permission: string;
289
+ [extra: string]: unknown;
290
+ }
291
+
292
+ /** `$secure` from the native plugin — secure key-value storage (native keychain or fallback). */
293
+ export interface ManifestSecure {
294
+ get(key: string): Promise<string | null>;
295
+ set(key: string, value: string): Promise<void>;
296
+ remove(key: string): Promise<void>;
297
+ keys(): Promise<string[]>;
298
+ clear(): Promise<void>;
299
+ use(adapter: unknown): void;
300
+ }
301
+
302
+ /** `$links` from the native plugin — deep/universal link handling. */
303
+ export interface ManifestLinks {
304
+ on(handler: (url: string) => void): void;
305
+ open(url: string): void;
306
+ readonly last: string | null;
307
+ }
308
+
309
+ /** `$app` from the native plugin — foreground/background state. */
310
+ export interface ManifestApp {
311
+ readonly active: boolean;
312
+ onChange(handler: (active: boolean) => void): void;
313
+ }
314
+
315
+ /** `$haptics` from the native plugin — haptic feedback with web vibration fallback. */
316
+ export interface ManifestHaptics {
317
+ impact(style?: string): Promise<unknown>;
318
+ notification(type?: string): Promise<unknown>;
319
+ [extra: string]: unknown;
320
+ }
321
+
322
+ /** `$biometric` from the native plugin. */
323
+ export interface ManifestBiometric {
324
+ available(): Promise<boolean>;
325
+ verify(opts?: Record<string, unknown>): Promise<unknown>;
326
+ }
327
+
328
+ /** `$camera` from the native plugin. */
329
+ export interface ManifestCamera {
330
+ photo(opts?: Record<string, unknown>): Promise<unknown>;
331
+ pick(opts?: Record<string, unknown>): Promise<unknown>;
332
+ }
333
+
334
+ /**
335
+ * Manifest's custom-element/attribute authoring surface (documentation aid —
336
+ * these are HTML attributes, not JS globals). Element styles pair with most.
337
+ */
338
+ export type ManifestDirective =
339
+ | 'x-route' | 'x-anchors'
340
+ | 'x-icon' | 'x-svg' | 'x-markdown' | 'x-code' | 'x-code-group'
341
+ | 'x-toast' | 'x-tooltip' | 'x-carousel' | 'x-virtual' | 'x-resize'
342
+ | 'x-chart' | 'x-date' | 'x-color' | 'x-colorpicker' | 'x-combobox'
343
+ | 'x-export' | 'x-pay' | 'x-files' | 'x-data-files';
344
+
191
345
  // ---------------------------------------------------------------------------
192
346
  // Global declarations (what Alpine exposes inside `x-data`, `x-show`, etc.)
193
347
  // ---------------------------------------------------------------------------
@@ -201,20 +355,50 @@ declare global {
201
355
  const $modify: ManifestModify;
202
356
  /** Run a callback safely, returning undefined on error. */
203
357
  const $try: ManifestTry;
204
- /** Appwrite auth plugin (only present when the plugin is loaded). */
358
+ /** Appwrite auth plugin (present when the plugin is loaded). */
205
359
  const $auth: ManifestAuth;
206
360
  /** Localization plugin. */
207
361
  const $locale: ManifestLocale;
208
362
  /** Toasts plugin. */
209
363
  const $toast: ManifestToast;
210
- /** Themes plugin. */
211
- const $colors: ManifestTheme;
212
- /** Colors plugin. */
213
- const $colors: ManifestColors;
364
+ /** Color-mode plugin (`$color.current = 'dark'`). */
365
+ const $color: ManifestColor;
214
366
  /** Colorpicker plugin. */
215
367
  const $colorpicker: ManifestColorpicker;
216
- /** URL parameters plugin. */
368
+ /** URL parameters plugin (`$url.tab.value`). */
217
369
  const $url: ManifestUrl;
370
+ /** Payments plugin. */
371
+ const $pay: ManifestPay;
372
+ /** Chat plugin. */
373
+ const $chat: ManifestChat;
374
+ /** Status plugin. */
375
+ const $status: ManifestStatus;
376
+ /** Appwrite presences plugin. */
377
+ const $presence: ManifestPresence;
378
+ /** Datepicker plugin. */
379
+ const $date: ManifestDate;
380
+ /** Charts plugin. */
381
+ const $chart: ManifestChart;
382
+ /** Export plugin. */
383
+ const $export: ManifestExport;
384
+ /** Device/platform info (utilities; enriched by the native plugin). */
385
+ const $device: ManifestDevice;
386
+ /** Native share (native plugin). */
387
+ const $share: ManifestShare;
388
+ /** Push permissions (native plugin). */
389
+ const $push: ManifestPush;
390
+ /** Secure storage (native plugin). */
391
+ const $secure: ManifestSecure;
392
+ /** Deep links (native plugin). */
393
+ const $links: ManifestLinks;
394
+ /** App foreground state (native plugin). */
395
+ const $app: ManifestApp;
396
+ /** Haptics (native plugin). */
397
+ const $haptics: ManifestHaptics;
398
+ /** Biometric auth (native plugin). */
399
+ const $biometric: ManifestBiometric;
400
+ /** Camera (native plugin). */
401
+ const $camera: ManifestCamera;
218
402
 
219
403
  /** Window-level Manifest namespace exposed by the loader. */
220
404
  interface Window {
@@ -1,3 +1,7 @@
1
+ /* manifest.data.js — built from scripts/data/ */
2
+
3
+ (function () {
4
+
1
5
  /* Manifest Data Sources - Configuration */
2
6
 
3
7
  // Load manifest if not already loaded (loader may set __manifestLoaded / registry.manifest).
@@ -856,6 +860,7 @@ function checkAndDispatchRenderReady() {
856
860
  'en';
857
861
  const sources = Object.keys(store).filter(k => !k.startsWith('_') && k !== 'all');
858
862
 
863
+ window.__manifestRenderReady = true;
859
864
  window.dispatchEvent(new CustomEvent('manifest:render-ready', {
860
865
  detail: { locale, sources }
861
866
  }));
@@ -1845,18 +1850,6 @@ window.ManifestDataAPI = {
1845
1850
 
1846
1851
 
1847
1852
 
1848
- /* Manifest Data Sources - Error Handling & Loading States */
1849
-
1850
- // Placeholder for Phase 4: Error handling and loading states
1851
- // This will be implemented in Phase 4
1852
-
1853
- // Export empty object for now
1854
- window.ManifestDataErrors = {
1855
- // Phase 4: Error handling will be added here
1856
- };
1857
-
1858
-
1859
-
1860
1853
  /* Manifest Data Sources - Unified Mutation System */
1861
1854
  // Handles optimistic updates, scoped updates, rollback, and background sync
1862
1855
 
@@ -2828,7 +2821,7 @@ function handleCircularReference({
2828
2821
  }
2829
2822
 
2830
2823
  if (shouldLog) {
2831
- console.warn(`[Proxy] ⚠️ CIRCULAR ${fullPath} | depth:${currentDepth} | triggered by:${triggeredBy} | This is likely Alpine re-evaluation`);
2824
+ console.warn(`[Manifest Data] ⚠️ CIRCULAR ${fullPath} | depth:${currentDepth} | triggered by:${triggeredBy} | This is likely Alpine re-evaluation`);
2832
2825
  }
2833
2826
 
2834
2827
  // Prop already in flight (Alpine re-evaluating): hand back the cached plain
@@ -2887,13 +2880,13 @@ function handleCircularReference({
2887
2880
  }
2888
2881
  } catch (e) {
2889
2882
  if (shouldLog) {
2890
- console.error(`[Proxy] ${fullPath} | Error in circular check:`, e);
2883
+ console.error(`[Manifest Data] ${fullPath} | Error in circular check:`, e);
2891
2884
  }
2892
2885
  }
2893
2886
 
2894
2887
  // If we can't return a cached copy, return undefined to break the cycle
2895
2888
  if (shouldLog) {
2896
- console.warn(`[Proxy] ${fullPath} | ⚠️ CIRCULAR - returning undefined to break cycle`);
2889
+ console.warn(`[Manifest Data] ${fullPath} | ⚠️ CIRCULAR - returning undefined to break cycle`);
2897
2890
  }
2898
2891
  if (activeProps) {
2899
2892
  activeProps.delete(propKey);
@@ -3221,6 +3214,40 @@ function attachArrayMethods(array, dataSourceName, reloadDataSource) {
3221
3214
  }
3222
3215
 
3223
3216
  const term = searchTerm.toLowerCase().trim();
3217
+
3218
+ // Weighted mode: $search(term, { title: 3, body: 1 }) — ranks by the
3219
+ // best-matching field's weight per whitespace-separated term (prefix
3220
+ // match gets a small boost); every term must match somewhere.
3221
+ const first = attributes[0];
3222
+ if (attributes.length === 1 && first && typeof first === 'object' && !Array.isArray(first)) {
3223
+ const fields = Object.keys(first);
3224
+ const terms = term.split(/\s+/).filter(Boolean);
3225
+ const scored = [];
3226
+ for (const item of array) {
3227
+ if (!item || typeof item !== 'object') continue;
3228
+ let total = 0, ok = true;
3229
+ for (const t of terms) {
3230
+ let best = 0;
3231
+ for (const f of fields) {
3232
+ const v = item[f];
3233
+ if (v == null) continue;
3234
+ const s = String(v).toLowerCase();
3235
+ if (!s.includes(t)) continue;
3236
+ let w = Number(first[f]) || 0;
3237
+ if (s.startsWith(t)) w *= 1.2;
3238
+ if (w > best) best = w;
3239
+ }
3240
+ if (!best) { ok = false; break; }
3241
+ total += best;
3242
+ }
3243
+ if (ok) scored.push([total, item]);
3244
+ }
3245
+ scored.sort((a, b) => b[0] - a[0]);
3246
+ const ranked = scored.map(e => e[1]);
3247
+ attachArrayMethods(ranked, dataSourceName, reloadDataSource);
3248
+ return ranked;
3249
+ }
3250
+
3224
3251
  const attrs = attributes.length > 0 ? attributes : Object.keys(array[0] || {});
3225
3252
 
3226
3253
  const filtered = array.filter(item => {
@@ -3630,7 +3657,7 @@ function createArrayProxyWithRoute(arrayTarget, dataSourceName = null, reloadDat
3630
3657
  });
3631
3658
  attachedMethods.push(methodName);
3632
3659
  } catch (e) {
3633
- console.warn(`[Array Proxy] Failed to attach ${methodName}:`, e);
3660
+ console.warn(`[Manifest Data] Failed to attach ${methodName}:`, e);
3634
3661
  }
3635
3662
  }
3636
3663
  });
@@ -3839,7 +3866,7 @@ function createArrayProxyWithRoute(arrayTarget, dataSourceName = null, reloadDat
3839
3866
  return bound;
3840
3867
  }
3841
3868
  // Return undefined if target is invalid
3842
- console.warn(`[Array Proxy] Could not provide array method: ${key}`, {
3869
+ console.warn(`[Manifest Data] Could not provide array method: ${key}`, {
3843
3870
  targetType: typeof target,
3844
3871
  hasLength: target && 'length' in target,
3845
3872
  lengthType: target && typeof target.length
@@ -4176,7 +4203,7 @@ function createArrayProxyWithRoute(arrayTarget, dataSourceName = null, reloadDat
4176
4203
  })()
4177
4204
  });
4178
4205
  } catch (e) {
4179
- console.warn(`[Array Proxy] Failed to define ${methodName} on proxy:`, e);
4206
+ console.warn(`[Manifest Data] Failed to define ${methodName} on proxy:`, e);
4180
4207
  }
4181
4208
  }
4182
4209
  });
@@ -5174,7 +5201,7 @@ function createRouteProxy(dataSourceData, pathKey, dataSourceName) {
5174
5201
  }
5175
5202
  return undefined;
5176
5203
  } catch (error) {
5177
- console.error('[Route Proxy Get] Error:', error);
5204
+ console.error('[Manifest Data] Error:', error);
5178
5205
  return undefined;
5179
5206
  }
5180
5207
  },
@@ -5364,7 +5391,7 @@ function createComputedFilesArray(tableName, entryId, bucketName, columnName = '
5364
5391
  errorState.value = bucketError;
5365
5392
 
5366
5393
  } catch (err) {
5367
- console.error('[createComputedFilesArray] Error recomputing files:', err);
5394
+ console.error('[Manifest Data] Error recomputing files:', err);
5368
5395
  errorState.value = err.message || 'Failed to compute files';
5369
5396
  loadingState.value = false;
5370
5397
  }
@@ -5859,7 +5886,7 @@ function createReactiveFileManager(tableName, entryId, bucketName, columnName) {
5859
5886
  }
5860
5887
  }
5861
5888
  }).catch(err => {
5862
- console.error('[ReactiveFileManager] Failed to load files after fileIds change:', err);
5889
+ console.error('[Manifest Data] Failed to load files after fileIds change:', err);
5863
5890
  });
5864
5891
  } else if (lastSeenFileIds === null) {
5865
5892
  // Initialize lastSeenFileIds on first run
@@ -5876,7 +5903,7 @@ function createReactiveFileManager(tableName, entryId, bucketName, columnName) {
5876
5903
  if (!fileIdsMatch && !loading && lastSeenFileIds !== null) {
5877
5904
  lastSeenFileIds = JSON.stringify(currentFileIds);
5878
5905
  loadFiles().catch(err => {
5879
- console.error('[ReactiveFileManager] Failed to reload files after sync check:', err);
5906
+ console.error('[Manifest Data] Failed to reload files after sync check:', err);
5880
5907
  });
5881
5908
  }
5882
5909
  }
@@ -5984,7 +6011,7 @@ async function getFilesForEntry(tableName, entryId, bucketId, fileIdsColumn = 'f
5984
6011
 
5985
6012
  // CRITICAL DEBUG: Log missing files to understand where stale fileIds come from
5986
6013
  if (missingFileIds.length > 0) {
5987
- console.warn('[getFilesForEntry] Found missing fileIds in database entry:', {
6014
+ console.warn('[Manifest Data] Found missing fileIds in database entry:', {
5988
6015
  tableName,
5989
6016
  entryId,
5990
6017
  missingFileIds,
@@ -6333,13 +6360,13 @@ async function unlinkFileFromAllEntries(fileId) {
6333
6360
  .then(() => {
6334
6361
  })
6335
6362
  .catch(error => {
6336
- console.debug('[Manifest Data] Could not unlink from', tableName, 'entry', entry.$id, ':', error.message);
6363
+ console.warn('[Manifest Data] Could not unlink from', tableName, 'entry', entry.$id, ':', error.message);
6337
6364
  })
6338
6365
  );
6339
6366
  }
6340
6367
  } catch (error) {
6341
6368
  // Silently continue - not all tables may have fileIds
6342
- console.debug('[Manifest Data] Could not process', tableName, ':', error.message);
6369
+ console.warn('[Manifest Data] Could not process', tableName, ':', error.message);
6343
6370
  }
6344
6371
  }
6345
6372
 
@@ -8423,6 +8450,19 @@ function registerXMagicMethod(loadDataSource) {
8423
8450
  return undefined;
8424
8451
  }
8425
8452
 
8453
+ // $x.$register(name, data) — install/replace a client-side source at
8454
+ // runtime (array or object). Reactive like any manifest.json source.
8455
+ if (prop === '$register') {
8456
+ return (name, data) => {
8457
+ if (!name || typeof name !== 'string') return undefined;
8458
+ const stamped = Array.isArray(data)
8459
+ ? data.map(d => (d && typeof d === 'object' && !('contentType' in d)) ? { contentType: name, ...d } : d)
8460
+ : data;
8461
+ window.ManifestDataStore?.updateStore?.(name, stamped, { loading: false, error: null, ready: true, allowDuringInit: true });
8462
+ return true;
8463
+ };
8464
+ }
8465
+
8426
8466
  // Resolve+cache from raw data BEFORE reading Alpine.store('data'):
8427
8467
  // the store read registers a reactive dep that can re-run this
8428
8468
  // effect and re-enter get() → stack overflow. Caching first makes
@@ -10145,7 +10185,7 @@ function registerFilesDirective() {
10145
10185
  const databaseIsStale = databaseFileIds && databaseFileIdsJson !== lastFileIds;
10146
10186
 
10147
10187
  if (storeIsStale || databaseIsStale) {
10148
- console.warn('[UPLOAD DEBUG] Store/Database fileIds is STALE - cleaning up:', {
10188
+ console.warn('[Manifest Data] Store/Database fileIds is STALE - cleaning up:', {
10149
10189
  directiveInstanceId,
10150
10190
  projectId: currentProjectId,
10151
10191
  storeFileIds: storeFileIdsJson,
@@ -10185,7 +10225,7 @@ function registerFilesDirective() {
10185
10225
  }
10186
10226
  }
10187
10227
  } catch (dbUpdateError) {
10188
- console.error('[UPLOAD DEBUG] Failed to update Appwrite database:', dbUpdateError);
10228
+ console.error('[Manifest Data] Failed to update Appwrite database:', dbUpdateError);
10189
10229
  // Don't throw - store is already updated, database will sync via realtime eventually
10190
10230
  }
10191
10231
  }
@@ -10853,7 +10893,7 @@ async function handleTableRealtimeEvent(dataSourceName, databaseId, tableId, sco
10853
10893
  // Incoming missing files + not clearly newer = stale event
10854
10894
  // racing an optimistic update; ignore it to protect the upload.
10855
10895
  if (isMissingFiles && !isDefinitelyNewer) {
10856
- console.warn('[Realtime] Ignoring stale realtime update (protecting optimistic update):', {
10896
+ console.warn('[Manifest Data] Ignoring stale realtime update (protecting optimistic update):', {
10857
10897
  projectId: row.$id,
10858
10898
  existingFileIds: existingFileIds,
10859
10899
  incomingFileIds: incomingFileIds,
@@ -11709,4 +11749,6 @@ if (typeof Alpine !== 'undefined') {
11709
11749
  }
11710
11750
 
11711
11751
  // Also listen for alpine:init (in case Alpine loads after DOMContentLoaded)
11712
- document.addEventListener('alpine:init', tryInitialize);
11752
+ document.addEventListener('alpine:init', tryInitialize);
11753
+
11754
+ })();
@@ -1,5 +1,7 @@
1
1
  /* Manifest Date Picker */
2
2
 
3
+ @layer base, components, utilities;
4
+
3
5
  @layer utilities {
4
6
 
5
7
  /* Picker container only (not trigger input/button) */
@@ -8,7 +10,7 @@
8
10
  min-width: 17rem;
9
11
  background: var(--color-popover-surface, oklch(98.5% 0 0));
10
12
  color: var(--color-content-stark, oklch(20.5% 0 0));
11
- border: 1px solid var(--color-line, color-mix(oklch(20.5% 0 0) 10%, transparent));
13
+ border: 1px solid var(--color-line, color-mix(in oklch, oklch(20.5% 0 0) 10%, transparent));
12
14
  border-radius: var(--radius, 0.5rem);
13
15
 
14
16
  /* Shell */
@@ -43,7 +45,7 @@
43
45
  transition: var(--transition, all .05s ease-in-out);
44
46
 
45
47
  &:hover {
46
- background: var(--color-field-surface, color-mix(oklch(20.5% 0 0) 10%, transparent));
48
+ background: var(--color-field-surface, color-mix(in oklch, oklch(20.5% 0 0) 10%, transparent));
47
49
  color: var(--color-content-stark, oklch(20.5% 0 0))
48
50
  }
49
51
  }
@@ -135,7 +137,7 @@
135
137
  transition: var(--transition, all .05s ease-in-out);
136
138
 
137
139
  &:hover:not(:disabled):not([aria-selected=true]) {
138
- background: var(--color-field-surface, color-mix(oklch(20.5% 0 0) 10%, transparent))
140
+ background: var(--color-field-surface, color-mix(in oklch, oklch(20.5% 0 0) 10%, transparent))
139
141
  }
140
142
 
141
143
  &:focus-visible {
@@ -151,7 +153,7 @@
151
153
 
152
154
  /* Today marker */
153
155
  &[aria-current=date]:not([aria-selected=true]) {
154
- border-color: var(--color-line, color-mix(oklch(20.5% 0 0) 18%, transparent));
156
+ border-color: var(--color-line, color-mix(in oklch, oklch(20.5% 0 0) 18%, transparent));
155
157
  font-weight: 600
156
158
  }
157
159
 
@@ -212,11 +214,11 @@
212
214
  transition: var(--transition, all .05s ease-in-out);
213
215
 
214
216
  &:hover:not(:disabled) {
215
- background: var(--color-field-surface, color-mix(oklch(20.5% 0 0) 10%, transparent))
217
+ background: var(--color-field-surface, color-mix(in oklch, oklch(20.5% 0 0) 10%, transparent))
216
218
  }
217
219
 
218
220
  &[aria-current=true] {
219
- border-color: var(--color-line, color-mix(oklch(20.5% 0 0) 18%, transparent));
221
+ border-color: var(--color-line, color-mix(in oklch, oklch(20.5% 0 0) 18%, transparent));
220
222
  font-weight: 600
221
223
  }
222
224
 
@@ -251,7 +253,7 @@
251
253
  padding-bottom: 0.5rem;
252
254
  padding-inline-start: 0.5rem;
253
255
  border: none;
254
- border-top: 1px solid var(--color-line, color-mix(oklch(20.5% 0 0) 10%, transparent));
256
+ border-top: 1px solid var(--color-line, color-mix(in oklch, oklch(20.5% 0 0) 10%, transparent));
255
257
 
256
258
  /* "Time" label */
257
259
  &>label {
@@ -307,7 +309,7 @@
307
309
 
308
310
  &:hover,
309
311
  &:focus {
310
- background: var(--color-field-surface, color-mix(oklch(20.5% 0 0) 10%, transparent))
312
+ background: var(--color-field-surface, color-mix(in oklch, oklch(20.5% 0 0) 10%, transparent))
311
313
  }
312
314
  }
313
315
 
@@ -334,7 +336,7 @@
334
336
  transition: var(--transition, all .05s ease-in-out);
335
337
 
336
338
  &:hover {
337
- background: var(--color-field-surface, color-mix(oklch(20.5% 0 0) 10%, transparent))
339
+ background: var(--color-field-surface, color-mix(in oklch, oklch(20.5% 0 0) 10%, transparent))
338
340
  }
339
341
  }
340
342
 
@@ -380,7 +382,7 @@
380
382
  width: 100%;
381
383
  contain: inline-size;
382
384
  padding: 0.5rem 0;
383
- border-top: 1px solid var(--color-line, color-mix(oklch(20.5% 0 0) 10%, transparent));
385
+ border-top: 1px solid var(--color-line, color-mix(in oklch, oklch(20.5% 0 0) 10%, transparent));
384
386
 
385
387
  /* Today | Clear buttons */
386
388
  &>button {
@@ -417,7 +419,7 @@
417
419
  padding: 0.25rem 0.625rem;
418
420
  font-size: 0.75rem;
419
421
  white-space: nowrap;
420
- background: var(--color-field-surface, color-mix(oklch(20.5% 0 0) 10%, transparent));
422
+ background: var(--color-field-surface, color-mix(in oklch, oklch(20.5% 0 0) 10%, transparent));
421
423
  color: var(--color-content-stark, oklch(20.5% 0 0));
422
424
  border: none;
423
425
  border-radius: calc(var(--radius, 0.5rem) * 2);
@@ -425,7 +427,7 @@
425
427
  transition: var(--transition, all .05s ease-in-out);
426
428
 
427
429
  &:hover {
428
- background: var(--color-field-surface-hover, color-mix(oklch(20.5% 0 0) 16%, transparent))
430
+ background: var(--color-field-surface-hover, color-mix(in oklch, oklch(20.5% 0 0) 16%, transparent))
429
431
  }
430
432
  }
431
433
  }
@@ -480,7 +482,7 @@
480
482
  transition: var(--transition, all .05s ease-in-out);
481
483
 
482
484
  &:hover {
483
- background: var(--color-field-surface, color-mix(oklch(20.5% 0 0) 10%, transparent))
485
+ background: var(--color-field-surface, color-mix(in oklch, oklch(20.5% 0 0) 10%, transparent))
484
486
  }
485
487
 
486
488
  &[aria-selected=true] {
@@ -1,5 +1,7 @@
1
1
  /* Manifest Dialogs */
2
2
 
3
+ @layer base, components, utilities;
4
+
3
5
  [popover]:not(.unstyle):not(:popover-open) {
4
6
  display: none;
5
7
  }
@@ -1,5 +1,7 @@
1
1
  /* Manifest Dividers */
2
2
 
3
+ @layer base, components, utilities;
4
+
3
5
  @layer utilities {
4
6
 
5
7
  :where(.divider) {
@@ -22,7 +24,7 @@
22
24
  flex: 1;
23
25
  width: auto;
24
26
  height: 1px;
25
- background-color: var(--color-line, color-mix(oklch(20.5% 0 0) 10%, transparent))
27
+ background-color: var(--color-line, color-mix(in oklch, oklch(20.5% 0 0) 10%, transparent))
26
28
  }
27
29
 
28
30
  /* Space between lines and content */