@fayz-ai/core 0.11.0 → 0.14.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.
Files changed (59) hide show
  1. package/dist/{chunk-BEGXYHS4.js → chunk-7GJTLBG3.js} +3 -3
  2. package/dist/{chunk-BEGXYHS4.js.map → chunk-7GJTLBG3.js.map} +1 -1
  3. package/dist/{chunk-V53GR4UT.js → chunk-IKZR3WSK.js} +3 -3
  4. package/dist/{chunk-V53GR4UT.js.map → chunk-IKZR3WSK.js.map} +1 -1
  5. package/dist/{chunk-LARZWDHA.js → chunk-KFBEKFII.js} +5 -4
  6. package/dist/chunk-KFBEKFII.js.map +1 -0
  7. package/dist/chunk-S5FOFKR4.js +1618 -0
  8. package/dist/chunk-S5FOFKR4.js.map +1 -0
  9. package/dist/{chunk-TDI6F6PT.js → chunk-X4FRQR2R.js} +10 -3
  10. package/dist/chunk-X4FRQR2R.js.map +1 -0
  11. package/dist/data/cached.d.ts +5 -1
  12. package/dist/data/cached.d.ts.map +1 -1
  13. package/dist/data/errors.d.ts +44 -0
  14. package/dist/data/errors.d.ts.map +1 -0
  15. package/dist/data/index.d.ts +8 -0
  16. package/dist/data/index.d.ts.map +1 -1
  17. package/dist/data/index.js +2 -2
  18. package/dist/data/offline.d.ts +45 -0
  19. package/dist/data/offline.d.ts.map +1 -0
  20. package/dist/data/query.d.ts +91 -0
  21. package/dist/data/query.d.ts.map +1 -0
  22. package/dist/data/resolve.d.ts.map +1 -1
  23. package/dist/data/types.d.ts +13 -0
  24. package/dist/data/types.d.ts.map +1 -1
  25. package/dist/events/bus.d.ts +12 -0
  26. package/dist/events/bus.d.ts.map +1 -0
  27. package/dist/events/index.d.ts +3 -11
  28. package/dist/events/index.d.ts.map +1 -1
  29. package/dist/i18n/index.d.ts.map +1 -1
  30. package/dist/i18n/index.js +1 -1
  31. package/dist/i18n/shell-translations.en.d.ts.map +1 -1
  32. package/dist/i18n/shell-translations.pt-br.d.ts.map +1 -1
  33. package/dist/index.d.ts +13 -3
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +191 -268
  36. package/dist/index.js.map +1 -1
  37. package/dist/integrations/index.js +2 -2
  38. package/dist/lib/cache-idb.d.ts +54 -0
  39. package/dist/lib/cache-idb.d.ts.map +1 -0
  40. package/dist/lib/cache.d.ts +2 -0
  41. package/dist/lib/cache.d.ts.map +1 -1
  42. package/dist/search/engine.d.ts.map +1 -1
  43. package/dist/search/types.d.ts +7 -0
  44. package/dist/search/types.d.ts.map +1 -1
  45. package/dist/{shell-translations.pt-br-BM5ZFSKJ.js → shell-translations.pt-br-PTOWYXNA.js} +7 -2
  46. package/dist/shell-translations.pt-br-PTOWYXNA.js.map +1 -0
  47. package/dist/testing/index.js +3 -3
  48. package/dist/types/analytics.d.ts +22 -0
  49. package/dist/types/analytics.d.ts.map +1 -1
  50. package/dist/types/crud.d.ts +20 -0
  51. package/dist/types/crud.d.ts.map +1 -1
  52. package/dist/types/plugins.d.ts +11 -0
  53. package/dist/types/plugins.d.ts.map +1 -1
  54. package/package.json +5 -5
  55. package/dist/chunk-LARZWDHA.js.map +0 -1
  56. package/dist/chunk-TDI6F6PT.js.map +0 -1
  57. package/dist/chunk-UVKH6RDX.js +0 -739
  58. package/dist/chunk-UVKH6RDX.js.map +0 -1
  59. package/dist/shell-translations.pt-br-BM5ZFSKJ.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,19 +1,19 @@
1
- export { PluginContractError, assertConnectorContract, assertPluginManifestContract, bespokeConnectorTables } from './chunk-V53GR4UT.js';
2
- export { CONNECTIONS_TABLE, CONNECTOR_CATEGORIES, ConnectionSettingsError, ConnectorRuntimeTokenUnavailableError, RequestBlockedError, RequestPlaneError, SYNC_RUNS_TABLE, assertSettingsAllowed, buyerIdempotencyKey, connectionKey, connectionRuns, connectionSettings, connectionStatus, connectorDirection, connectorEntities, connectorGrantScopes, connectorPermissions, connectorPlanes, connectorRuntimeToken, connectorSettings, connectorSubscribes, connectorSubscribesTo, createConnectionStore, createRpcEffectLedger, eventKeyMatches, getConnectorRuntimeTokenSource, grants, groupedPermissions, hasRequestPlane, hasSensitivePermission, invocationPlane, isConnectorCategory, isDataPermission, isEventPermission, isSettingSet, listConnections, missingRequiredSettings, permissionActions, permissionsWrite, preferredPlane, requestPlaneSpec, runEffect, runRequest, setConnectorRuntimeTokenSource, settingsStatus, setupStatusDetail, sortedPermissions, withAfterHooks } from './chunk-BEGXYHS4.js';
1
+ export { PluginContractError, assertConnectorContract, assertPluginManifestContract, bespokeConnectorTables } from './chunk-IKZR3WSK.js';
2
+ export { CONNECTIONS_TABLE, CONNECTOR_CATEGORIES, ConnectionSettingsError, ConnectorRuntimeTokenUnavailableError, RequestBlockedError, RequestPlaneError, SYNC_RUNS_TABLE, assertSettingsAllowed, buyerIdempotencyKey, connectionKey, connectionRuns, connectionSettings, connectionStatus, connectorDirection, connectorEntities, connectorGrantScopes, connectorPermissions, connectorPlanes, connectorRuntimeToken, connectorSettings, connectorSubscribes, connectorSubscribesTo, createConnectionStore, createRpcEffectLedger, eventKeyMatches, getConnectorRuntimeTokenSource, grants, groupedPermissions, hasRequestPlane, hasSensitivePermission, invocationPlane, isConnectorCategory, isDataPermission, isEventPermission, isSettingSet, listConnections, missingRequiredSettings, permissionActions, permissionsWrite, preferredPlane, requestPlaneSpec, runEffect, runRequest, setConnectorRuntimeTokenSource, settingsStatus, setupStatusDetail, sortedPermissions, withAfterHooks } from './chunk-7GJTLBG3.js';
3
3
  export { CONNECTOR_RUNTIME_TOKEN_HEADER, ConnectorHttpError, RateLimitExceededError, advanceWindow, backoffDelay, classify, createRateLimiter, cursorCompleteness, fetchWithRetry, isExpiring, paginate, parseRetryAfter, reconcileMirror, serializeCursor, sliceWindow, statusNeedsBody } from './chunk-ED6NBH6U.js';
4
- import { resolveDataProvider } from './chunk-UVKH6RDX.js';
5
- export { CustomFieldsError, FIELDS_TABLE, bulkCreate, bulkRemove, clearCustomFieldsCache, countByTenant, createArchetypeProvider, createFayzApiProvider, createMockProvider, invalidateCount, mergeCustomFields, resolveCustomFields, resolveDataProvider, validateCustomFields, withCache } from './chunk-UVKH6RDX.js';
6
- import { getActiveTenantId, globalCache, getSupabaseClientOptional } from './chunk-LARZWDHA.js';
7
- export { applyRangeToQuery, clearGlobalCache, createCacheStore, createSupabaseProvider, getActiveTenantId, getSupabaseClientOptional, globalCache, isFilterObject, matchesRange, parseRangeFilter, setActiveTenantId, setGlobalSupabaseClient, stableKey, subscribeActiveTenant, useActiveTenantId } from './chunk-LARZWDHA.js';
4
+ import { eventBus, DATA_CHANGED_EVENT, resolveDataProvider } from './chunk-S5FOFKR4.js';
5
+ export { CustomFieldsError, DATA_CHANGED_EVENT, DataError, FIELDS_TABLE, attachPersistentCache, bulkCreate, bulkRemove, cacheKeyFor, cachePrefixFor, clearCustomFieldsCache, countByTenant, createArchetypeProvider, createEventBus, createFayzApiProvider, createMockProvider, dataCall, dataQuery, emitDataChanged, eventBus, getPersistentCache, invalidateCount, localList, matchesDataChange, mergeCustomFields, registerDataTelemetry, replicaKeyFor, resolveCustomFields, resolveDataProvider, syncReplica, toDataError, useDataChanged, validateCustomFields, withCache, withOffline } from './chunk-S5FOFKR4.js';
6
+ import { getActiveTenantId, getSupabaseClientOptional } from './chunk-KFBEKFII.js';
7
+ export { DEFAULT_CACHE_TTL, applyRangeToQuery, clearGlobalCache, createCacheStore, createSupabaseProvider, getActiveTenantId, getSupabaseClientOptional, globalCache, isFilterObject, matchesRange, parseRangeFilter, setActiveTenantId, setGlobalSupabaseClient, stableKey, subscribeActiveTenant, useActiveTenantId } from './chunk-KFBEKFII.js';
8
8
  import { getBlock, checkNodePlacement, getScaffold } from './chunk-RRYFXUQX.js';
9
9
  export { BLOCK_SETTING_TYPES, PLUGIN_API_VERSION, PluginRuntimeProvider, auditBlocks, blockRegistry, buildEntityDomainEvents, checkAgainstSchema, checkBlockConstraints, checkBlockContext, checkNodePlacement, clearExtensionPoints, clearHandles, clearLoaders, componentRegistry, dataNeedKey, defaultPropsFromSettings, defineBlock, defineExtensionPoint, defineLoader, definePlugin, describeBlock, describeBlocks, describeExtensionPoints, describeLoaders, entityEventKey, extensionAfterHooks, extensionPointRegistry, formatSchemaIssues, getAnalyticsCards, getBlock, getBlockMeta, getComponent, getDashboardWidgets, getHandle, getMetric, getPage, getPlugin, getPluginFactory, getScaffold, getWidgetsForZone, handleNameFor, handleRegistry, hasExtensionPoint, hasHandle, hasLoader, isBlockEnabledOn, isLoaderParamRef, isLoaderPropRef, listBlocks, listExtensionHandlers, listExtensionPoints, listHandles, listLoaders, listMetrics, listPluginFactories, listPlugins, loaderRegistry, metricRegistry, pageRegistry, pluginFactoryRegistry, pluginRegistry, registerBlock, registerComponent, registerExtensionHandler, registerHandle, registerMetric, registerPage, registerPlugin, registerPluginFactory, registerScaffold, repairBlockTree, resolveHandle, resolveLoader, resolvePluginComponent, resolvePluginRuntime, runEscapeValve, runExtensionPoint, scaffoldRegistry, settingsToJsonSchema, summarizeBlockAudit, unregisterExtensionHandler, useConnectorsForPlugin, usePluginRuntime, usePluginRuntimeOptional } from './chunk-RRYFXUQX.js';
10
10
  export { ENTITY_FIELD_TYPES, GENERIC_ENTITY_TABLE, RESERVED_ENTITY_FIELDS, Registry, clearCustomFieldsDeclarations, clearEntityDeclarations, customFieldsRegistry, declaredCustomFields, defineCustomFields, defineEntity, describeEntities, entityAdminForm, entityDeclarationRegistry, entityRecordSchema, hasCustomFieldsDeclaration, hasEntityDeclaration, isCustomId, listEntityDeclarations, resolveEntityDeclaration, validateEntityRecordData } from './chunk-EWKX4VUM.js';
11
11
  export { clearEntityRegistry, deriveEntityKey, getAllEntities, getEntityByKey, registerEntity } from './chunk-CU64QI4A.js';
12
- import { getCurrentLocale } from './chunk-TDI6F6PT.js';
13
- export { I18nProvider, coreTranslations, getCurrentLocale, mergeTranslations, preloadLocale, registerTranslations, setCurrentLocale, setLocaleStore, tl, useI18nConfig, useTranslation } from './chunk-TDI6F6PT.js';
12
+ import { getCurrentLocale } from './chunk-X4FRQR2R.js';
13
+ export { I18nProvider, coreTranslations, getCurrentLocale, mergeTranslations, preloadLocale, registerTranslations, setCurrentLocale, setLocaleStore, tl, useI18nConfig, useTranslation } from './chunk-X4FRQR2R.js';
14
14
  export { defaultRouterAdapter, hashRouterAdapter, historyRouterAdapter, hostRouterAdapter, staticRouterAdapter, windowRouterAdapter } from './chunk-OXQGRJZT.js';
15
15
  export { FayzRuntimeError, createFayzRuntimeClient } from './chunk-7RTUHSKY.js';
16
- import * as React3 from 'react';
16
+ import * as React2 from 'react';
17
17
  import { useEffect } from 'react';
18
18
  import { create } from 'zustand';
19
19
 
@@ -53,233 +53,6 @@ function resolveBackendEnv(options = {}) {
53
53
  };
54
54
  }
55
55
 
56
- // src/events/envelope.ts
57
- function emitDomainEvent(key, payload, meta) {
58
- const event = {
59
- key,
60
- payload,
61
- actorId: meta?.actorId ?? null,
62
- tenantId: meta?.tenantId ?? null,
63
- subject: meta?.subject ?? null,
64
- occurredAt: meta?.occurredAt ?? (/* @__PURE__ */ new Date()).toISOString()
65
- };
66
- eventBus.emit(key, event);
67
- for (const sink of sinks) {
68
- try {
69
- sink(event);
70
- } catch (err) {
71
- console.warn("[events] sink failed", err);
72
- }
73
- }
74
- return event;
75
- }
76
- var sinks = /* @__PURE__ */ new Set();
77
- function registerEventSink(sink) {
78
- sinks.add(sink);
79
- return () => {
80
- sinks.delete(sink);
81
- };
82
- }
83
- function clearEventSinks() {
84
- sinks.clear();
85
- }
86
- function onDomainEvent(key, handler) {
87
- return eventBus.on(key, (e) => {
88
- void handler(e);
89
- });
90
- }
91
- function onDomainEvents(keys, known, handler) {
92
- const matched = known.filter((k) => keys.some((p) => p === "*" || (p.endsWith(".*") ? k.startsWith(p.slice(0, -1)) : p === k)));
93
- const offs = matched.map((k) => onDomainEvent(k, handler));
94
- return () => {
95
- for (const off of offs) off();
96
- };
97
- }
98
- function sampleEventPayload(fields) {
99
- const out = {};
100
- for (const f of fields ?? []) out[f.name] = f.example ?? `{{${f.name}}}`;
101
- return out;
102
- }
103
-
104
- // src/events/log.ts
105
- var EVENT_LOG_TABLE = "plg_event_log";
106
- function client() {
107
- return getSupabaseClientOptional();
108
- }
109
- function toRun(row) {
110
- return {
111
- id: row.id,
112
- eventKey: row.event_key,
113
- status: row.status ?? "recorded",
114
- payload: row.payload ?? {},
115
- result: row.result ?? null,
116
- error: row.error ?? null,
117
- actorId: row.actor_id ?? null,
118
- subjectType: row.subject_type ?? null,
119
- subjectId: row.subject_id ?? null,
120
- occurredAt: row.occurred_at ?? row.created_at
121
- };
122
- }
123
- var pending = [];
124
- var flushing = false;
125
- function flushSoon() {
126
- if (flushing) return;
127
- flushing = true;
128
- queueMicrotask(() => {
129
- const rows = pending;
130
- pending = [];
131
- flushing = false;
132
- if (!rows.length) return;
133
- const db = client();
134
- if (!db) return;
135
- void (async () => {
136
- try {
137
- await db.from(EVENT_LOG_TABLE).insert(rows);
138
- } catch (err) {
139
- console.warn("[events] could not record run", err);
140
- }
141
- })();
142
- });
143
- }
144
- function recordEventRun(event, status = "recorded") {
145
- const db = client();
146
- if (!db) return;
147
- const tenantId = event.tenantId ?? getActiveTenantId();
148
- if (!tenantId) return;
149
- pending.push({
150
- tenant_id: tenantId,
151
- event_key: event.key,
152
- status,
153
- payload: event.payload ?? {},
154
- actor_id: event.actorId ?? null,
155
- subject_type: event.subject?.type ?? null,
156
- subject_id: event.subject?.id ?? null,
157
- occurred_at: event.occurredAt
158
- });
159
- flushSoon();
160
- }
161
- var started = false;
162
- function startEventLog() {
163
- if (started) return () => {
164
- };
165
- started = true;
166
- const off = registerEventSink((event) => recordEventRun(event));
167
- return () => {
168
- off();
169
- started = false;
170
- };
171
- }
172
- async function loadEventRuns(eventKey, options) {
173
- const db = client();
174
- if (!db) return [];
175
- try {
176
- let q = db.from(EVENT_LOG_TABLE).select("*").eq("event_key", eventKey).order("occurred_at", { ascending: false }).limit(options?.limit ?? 20);
177
- if (options?.tenantId) q = q.eq("tenant_id", options.tenantId);
178
- const { data, error } = await q;
179
- if (error) throw error;
180
- return (data ?? []).map(toRun);
181
- } catch (err) {
182
- console.warn("[events] could not load runs", err);
183
- return [];
184
- }
185
- }
186
-
187
- // src/events/index.tsx
188
- function createEventBus() {
189
- const handlers = /* @__PURE__ */ new Map();
190
- const bus = {
191
- emit(event, payload) {
192
- const set = handlers.get(event);
193
- if (!set) return;
194
- for (const handler of Array.from(set)) {
195
- try {
196
- handler(payload);
197
- } catch (err) {
198
- console.error(`[fayz] event handler for "${event}" threw:`, err);
199
- }
200
- }
201
- },
202
- on(event, handler) {
203
- let set = handlers.get(event);
204
- if (!set) {
205
- set = /* @__PURE__ */ new Set();
206
- handlers.set(event, set);
207
- }
208
- set.add(handler);
209
- return () => bus.off(event, handler);
210
- },
211
- once(event, handler) {
212
- const wrapped = (payload) => {
213
- bus.off(event, wrapped);
214
- handler(payload);
215
- };
216
- return bus.on(event, wrapped);
217
- },
218
- off(event, handler) {
219
- handlers.get(event)?.delete(handler);
220
- },
221
- clear(event) {
222
- if (event) handlers.delete(event);
223
- else handlers.clear();
224
- }
225
- };
226
- return bus;
227
- }
228
- var eventBus = createEventBus();
229
- function useOnEvent(event, handler, deps = []) {
230
- const ref = React3.useRef(handler);
231
- ref.current = handler;
232
- React3.useEffect(
233
- () => eventBus.on(event, (payload) => ref.current(payload)),
234
- // eslint-disable-next-line react-hooks/exhaustive-deps
235
- [event, ...deps]
236
- );
237
- }
238
-
239
- // src/data/refresh.ts
240
- var DATA_CHANGED_EVENT = "data:changed";
241
- function matchesDataChange(match, payload) {
242
- const attributed = payload.table ?? payload.entityKey ?? payload.archetype;
243
- if (!attributed) return true;
244
- if (match.table && payload.table && match.table === payload.table) return true;
245
- if (match.entityKey && payload.entityKey && match.entityKey === payload.entityKey) return true;
246
- if (match.archetype && payload.archetype && match.archetype === payload.archetype) return true;
247
- return !match.table && !match.entityKey && !match.archetype;
248
- }
249
- var pending2 = [];
250
- var flushTimer = null;
251
- function flush() {
252
- const batch = pending2;
253
- pending2 = [];
254
- flushTimer = null;
255
- for (const payload of batch) eventBus.emit(DATA_CHANGED_EVENT, payload);
256
- }
257
- function emitDataChanged(payload = {}) {
258
- if (payload.table) {
259
- const tenant = getActiveTenantId() ?? "_";
260
- const sibling = payload.table.startsWith("v_") ? payload.table.slice(2) : `v_${payload.table}`;
261
- globalCache.invalidate(`${tenant}:${payload.table}`);
262
- globalCache.invalidate(`${tenant}:${sibling}`);
263
- } else {
264
- globalCache.clear();
265
- }
266
- pending2.push({ op: "unknown", source: "agent", ...payload });
267
- if (flushTimer) return;
268
- flushTimer = setTimeout(flush, 120);
269
- }
270
- function useDataChanged(match, handler, deps = []) {
271
- const handlerRef = React3.useRef(handler);
272
- handlerRef.current = handler;
273
- const { table, entityKey, archetype } = match;
274
- React3.useEffect(
275
- () => eventBus.on(DATA_CHANGED_EVENT, (payload) => {
276
- if (matchesDataChange({ table, entityKey, archetype }, payload)) handlerRef.current(payload);
277
- }),
278
- // eslint-disable-next-line react-hooks/exhaustive-deps
279
- [table, entityKey, archetype, ...deps]
280
- );
281
- }
282
-
283
56
  // src/plugin/createSafeDataProvider.ts
284
57
  function createSafeDataProvider(makeSupabase, makeMock) {
285
58
  let resolved = null;
@@ -604,6 +377,148 @@ function exportCSV(columns, rows, filename) {
604
377
  downloadCSV(buildCSV(columns, rows), filename);
605
378
  }
606
379
 
380
+ // src/events/envelope.ts
381
+ function emitDomainEvent(key, payload, meta) {
382
+ const event = {
383
+ key,
384
+ payload,
385
+ actorId: meta?.actorId ?? null,
386
+ tenantId: meta?.tenantId ?? null,
387
+ subject: meta?.subject ?? null,
388
+ occurredAt: meta?.occurredAt ?? (/* @__PURE__ */ new Date()).toISOString()
389
+ };
390
+ eventBus.emit(key, event);
391
+ for (const sink of sinks) {
392
+ try {
393
+ sink(event);
394
+ } catch (err) {
395
+ console.warn("[events] sink failed", err);
396
+ }
397
+ }
398
+ return event;
399
+ }
400
+ var sinks = /* @__PURE__ */ new Set();
401
+ function registerEventSink(sink) {
402
+ sinks.add(sink);
403
+ return () => {
404
+ sinks.delete(sink);
405
+ };
406
+ }
407
+ function clearEventSinks() {
408
+ sinks.clear();
409
+ }
410
+ function onDomainEvent(key, handler) {
411
+ return eventBus.on(key, (e) => {
412
+ void handler(e);
413
+ });
414
+ }
415
+ function onDomainEvents(keys, known, handler) {
416
+ const matched = known.filter((k) => keys.some((p) => p === "*" || (p.endsWith(".*") ? k.startsWith(p.slice(0, -1)) : p === k)));
417
+ const offs = matched.map((k) => onDomainEvent(k, handler));
418
+ return () => {
419
+ for (const off of offs) off();
420
+ };
421
+ }
422
+ function sampleEventPayload(fields) {
423
+ const out = {};
424
+ for (const f of fields ?? []) out[f.name] = f.example ?? `{{${f.name}}}`;
425
+ return out;
426
+ }
427
+
428
+ // src/events/log.ts
429
+ var EVENT_LOG_TABLE = "plg_event_log";
430
+ function client() {
431
+ return getSupabaseClientOptional();
432
+ }
433
+ function toRun(row) {
434
+ return {
435
+ id: row.id,
436
+ eventKey: row.event_key,
437
+ status: row.status ?? "recorded",
438
+ payload: row.payload ?? {},
439
+ result: row.result ?? null,
440
+ error: row.error ?? null,
441
+ actorId: row.actor_id ?? null,
442
+ subjectType: row.subject_type ?? null,
443
+ subjectId: row.subject_id ?? null,
444
+ occurredAt: row.occurred_at ?? row.created_at
445
+ };
446
+ }
447
+ var pending = [];
448
+ var flushing = false;
449
+ function flushSoon() {
450
+ if (flushing) return;
451
+ flushing = true;
452
+ queueMicrotask(() => {
453
+ const rows = pending;
454
+ pending = [];
455
+ flushing = false;
456
+ if (!rows.length) return;
457
+ const db = client();
458
+ if (!db) return;
459
+ void (async () => {
460
+ try {
461
+ await db.from(EVENT_LOG_TABLE).insert(rows);
462
+ } catch (err) {
463
+ console.warn("[events] could not record run", err);
464
+ }
465
+ })();
466
+ });
467
+ }
468
+ function recordEventRun(event, status = "recorded") {
469
+ const db = client();
470
+ if (!db) return;
471
+ const tenantId = event.tenantId ?? getActiveTenantId();
472
+ if (!tenantId) return;
473
+ pending.push({
474
+ tenant_id: tenantId,
475
+ event_key: event.key,
476
+ status,
477
+ payload: event.payload ?? {},
478
+ actor_id: event.actorId ?? null,
479
+ subject_type: event.subject?.type ?? null,
480
+ subject_id: event.subject?.id ?? null,
481
+ occurred_at: event.occurredAt
482
+ });
483
+ flushSoon();
484
+ }
485
+ var started = false;
486
+ function startEventLog() {
487
+ if (started) return () => {
488
+ };
489
+ started = true;
490
+ const off = registerEventSink((event) => recordEventRun(event));
491
+ return () => {
492
+ off();
493
+ started = false;
494
+ };
495
+ }
496
+ async function loadEventRuns(eventKey, options) {
497
+ const db = client();
498
+ if (!db) return [];
499
+ try {
500
+ let q = db.from(EVENT_LOG_TABLE).select("*").eq("event_key", eventKey).order("occurred_at", { ascending: false }).limit(options?.limit ?? 20);
501
+ if (options?.tenantId) q = q.eq("tenant_id", options.tenantId);
502
+ const { data, error } = await q;
503
+ if (error) throw error;
504
+ return (data ?? []).map(toRun);
505
+ } catch (err) {
506
+ console.warn("[events] could not load runs", err);
507
+ return [];
508
+ }
509
+ }
510
+
511
+ // src/events/index.tsx
512
+ function useOnEvent(event, handler, deps = []) {
513
+ const ref = React2.useRef(handler);
514
+ ref.current = handler;
515
+ React2.useEffect(
516
+ () => eventBus.on(event, (payload) => ref.current(payload)),
517
+ // eslint-disable-next-line react-hooks/exhaustive-deps
518
+ [event, ...deps]
519
+ );
520
+ }
521
+
607
522
  // src/search/text.ts
608
523
  var COMBINING_MARKS = /[\u0300-\u036f]/g;
609
524
  function foldText(value) {
@@ -919,7 +834,8 @@ function assemble(query, hits, targets, opts) {
919
834
  via: opts.via,
920
835
  failed: opts.failed,
921
836
  elapsedMs: opts.elapsedMs,
922
- partial: opts.partial ?? false
837
+ partial: opts.partial ?? false,
838
+ cached: opts.cached ?? opts.via === "cache"
923
839
  };
924
840
  }
925
841
  var cache = [];
@@ -1036,7 +952,7 @@ async function mapLimited(items, limit, fn) {
1036
952
  await Promise.all(workers);
1037
953
  return results;
1038
954
  }
1039
- async function searchViaScan(query, targets, perTarget, onProgress) {
955
+ async function searchViaScan(query, targets, perTarget, onProgress, fresh) {
1040
956
  const multiWord = query.tokens.length > 1;
1041
957
  const phrase = query.folded;
1042
958
  const token = query.anchor.length >= MIN_QUERY_LENGTH ? query.anchor : phrase;
@@ -1044,12 +960,16 @@ async function searchViaScan(query, targets, perTarget, onProgress) {
1044
960
  const widePageSize = Math.min(perTarget * 6, 40);
1045
961
  const searchable = targets.filter((t) => searchableKeys(t.entity).length > 0);
1046
962
  const running = [];
963
+ let anyCached = false;
1047
964
  const round = (search, size) => mapLimited(searchable, SCAN_CONCURRENCY, async (target) => {
1048
- const provider = resolveDataProvider(target.entity, target.mockData);
965
+ const provider = resolveDataProvider(target.entity, target.mockData, {
966
+ cache: fresh ? false : void 0
967
+ });
1049
968
  const result = await withTimeout(
1050
969
  provider.list({ search, pageSize: size, countMode: "none" }),
1051
970
  TARGET_TIMEOUT_MS
1052
971
  );
972
+ if (result.cached || result.stale) anyCached = true;
1053
973
  const rows = result.data;
1054
974
  const hits = rows.map((row) => hitFromRow(target, row, query)).filter((h) => h !== null);
1055
975
  if (hits.length && onProgress) {
@@ -1068,9 +988,9 @@ async function searchViaScan(query, targets, perTarget, onProgress) {
1068
988
  return { hits, failed };
1069
989
  };
1070
990
  const first = collect(await round(phrase, pageSize));
1071
- if (first.hits.length > 0 || !multiWord || token === phrase) return first;
991
+ if (first.hits.length > 0 || !multiWord || token === phrase) return { ...first, cached: anyCached };
1072
992
  const second = collect(await round(token, widePageSize));
1073
- return { hits: second.hits, failed: [.../* @__PURE__ */ new Set([...first.failed, ...second.failed])] };
993
+ return { hits: second.hits, failed: [.../* @__PURE__ */ new Set([...first.failed, ...second.failed])], cached: anyCached };
1074
994
  }
1075
995
  async function searchEverything(rawQuery, options) {
1076
996
  const started2 = Date.now();
@@ -1081,7 +1001,7 @@ async function searchEverything(rawQuery, options) {
1081
1001
  const empty = (via2) => assemble(rawQuery, [], targets, { via: via2, failed: [], elapsedMs: Date.now() - started2, perTarget, limit });
1082
1002
  if (query.folded.length < MIN_QUERY_LENGTH || targets.length === 0) return empty("cache");
1083
1003
  const scope = scopeKey(targets);
1084
- const exact = cacheGet(scope, query.folded);
1004
+ const exact = options.fresh ? void 0 : cacheGet(scope, query.folded);
1085
1005
  if (exact) {
1086
1006
  return assemble(rawQuery, exact.hits, targets, {
1087
1007
  via: "cache",
@@ -1091,7 +1011,7 @@ async function searchEverything(rawQuery, options) {
1091
1011
  limit
1092
1012
  });
1093
1013
  }
1094
- if (options.onPartial) {
1014
+ if (options.onPartial && !options.fresh) {
1095
1015
  const prefix = cachePrefix(scope, query.folded);
1096
1016
  if (prefix) {
1097
1017
  const rescored = prefix.hits.map((hit) => {
@@ -1115,6 +1035,7 @@ async function searchEverything(rawQuery, options) {
1115
1035
  let hits = [];
1116
1036
  let failed = [];
1117
1037
  let via = "scan";
1038
+ let anyCached = false;
1118
1039
  if (!options.forceScan && indexAvailable !== false) {
1119
1040
  try {
1120
1041
  const indexed = await searchViaIndex(query, targets, perTarget, limit);
@@ -1134,9 +1055,10 @@ async function searchEverything(rawQuery, options) {
1134
1055
  perTarget,
1135
1056
  limit,
1136
1057
  partial: true
1137
- })) : void 0);
1058
+ })) : void 0, options.fresh);
1138
1059
  hits = scanned.hits;
1139
1060
  failed = scanned.failed;
1061
+ anyCached = scanned.cached;
1140
1062
  }
1141
1063
  if (options.signal?.aborted) return empty(via);
1142
1064
  const result = assemble(rawQuery, hits, targets, {
@@ -1144,7 +1066,8 @@ async function searchEverything(rawQuery, options) {
1144
1066
  failed,
1145
1067
  elapsedMs: Date.now() - started2,
1146
1068
  perTarget,
1147
- limit
1069
+ limit,
1070
+ cached: anyCached
1148
1071
  });
1149
1072
  cacheSet({
1150
1073
  scope,
@@ -1176,15 +1099,15 @@ function blockEditorMode() {
1176
1099
  }
1177
1100
  var BLOCK_PATH_ATTRIBUTE = "data-fayz-block";
1178
1101
  var BLOCK_TYPE_ATTRIBUTE = "data-fayz-block-type";
1179
- var BlockPathContext = React3.createContext("");
1102
+ var BlockPathContext = React2.createContext("");
1180
1103
  function useBlockPath() {
1181
- return React3.useContext(BlockPathContext);
1104
+ return React2.useContext(BlockPathContext);
1182
1105
  }
1183
1106
  function getBlockErrorVisibility() {
1184
1107
  return errorVisibility ?? defaultVisibility();
1185
1108
  }
1186
1109
  function BlockErrorCard({ title, detail }) {
1187
- return React3.createElement(
1110
+ return React2.createElement(
1188
1111
  "div",
1189
1112
  {
1190
1113
  "data-block-error": title,
@@ -1197,14 +1120,14 @@ function BlockErrorCard({ title, detail }) {
1197
1120
  }
1198
1121
  },
1199
1122
  title,
1200
- detail ? React3.createElement("div", { style: { opacity: 0.8, marginTop: 4 } }, detail) : null
1123
+ detail ? React2.createElement("div", { style: { opacity: 0.8, marginTop: 4 } }, detail) : null
1201
1124
  );
1202
1125
  }
1203
1126
  function UnknownBlock({ type }) {
1204
1127
  if (getBlockErrorVisibility() === "silent") return null;
1205
- return React3.createElement(BlockErrorCard, { title: `Unknown block: "${type}"` });
1128
+ return React2.createElement(BlockErrorCard, { title: `Unknown block: "${type}"` });
1206
1129
  }
1207
- var BlockErrorBoundary = class extends React3.Component {
1130
+ var BlockErrorBoundary = class extends React2.Component {
1208
1131
  constructor() {
1209
1132
  super(...arguments);
1210
1133
  this.state = { error: null };
@@ -1218,22 +1141,22 @@ var BlockErrorBoundary = class extends React3.Component {
1218
1141
  render() {
1219
1142
  if (!this.state.error) return this.props.children;
1220
1143
  if (getBlockErrorVisibility() === "silent") return null;
1221
- return React3.createElement(BlockErrorCard, {
1144
+ return React2.createElement(BlockErrorCard, {
1222
1145
  title: `Block "${this.props.blockType}" crashed`,
1223
1146
  detail: this.state.error.message
1224
1147
  });
1225
1148
  }
1226
1149
  };
1227
- var BlockAncestryContext = React3.createContext([]);
1150
+ var BlockAncestryContext = React2.createContext([]);
1228
1151
  function ConstraintViolation({ detail }) {
1229
1152
  if (getBlockErrorVisibility() === "silent") return null;
1230
- return React3.createElement(BlockErrorCard, { title: "Misplaced block", detail });
1153
+ return React2.createElement(BlockErrorCard, { title: "Misplaced block", detail });
1231
1154
  }
1232
1155
  var warnedViolations = /* @__PURE__ */ new Set();
1233
1156
  function BlockRenderer({ node, path }) {
1234
- const ancestry = React3.useContext(BlockAncestryContext);
1157
+ const ancestry = React2.useContext(BlockAncestryContext);
1235
1158
  const Comp = getBlock(node.type);
1236
- if (!Comp) return React3.createElement(UnknownBlock, { type: node.type });
1159
+ if (!Comp) return React2.createElement(UnknownBlock, { type: node.type });
1237
1160
  const violations = checkNodePlacement(node.type, ancestry);
1238
1161
  if (violations.length > 0) {
1239
1162
  const message = violations.map((v) => v.detail).join("; ");
@@ -1241,23 +1164,23 @@ function BlockRenderer({ node, path }) {
1241
1164
  warnedViolations.add(message);
1242
1165
  console.warn(`[blocks] ${message}`);
1243
1166
  }
1244
- return React3.createElement(ConstraintViolation, { detail: violations[0].detail });
1167
+ return React2.createElement(ConstraintViolation, { detail: violations[0].detail });
1245
1168
  }
1246
1169
  const childEls = node.children?.length ? renderBlocks(node.children, path ? `${path}.children` : void 0) : null;
1247
- const rendered = React3.createElement(
1170
+ const rendered = React2.createElement(
1248
1171
  BlockAncestryContext.Provider,
1249
1172
  { value: ancestry.length ? [...ancestry, node.type] : [node.type] },
1250
- React3.createElement(
1173
+ React2.createElement(
1251
1174
  BlockErrorBoundary,
1252
1175
  { blockType: node.type },
1253
- React3.createElement(Comp, { ...node.props ?? {}, node }, childEls)
1176
+ React2.createElement(Comp, { ...node.props ?? {}, node }, childEls)
1254
1177
  )
1255
1178
  );
1256
1179
  if (!editorMode || !path) return rendered;
1257
- return React3.createElement(
1180
+ return React2.createElement(
1258
1181
  BlockPathContext.Provider,
1259
1182
  { value: path },
1260
- React3.createElement(
1183
+ React2.createElement(
1261
1184
  "div",
1262
1185
  {
1263
1186
  [BLOCK_PATH_ATTRIBUTE]: path,
@@ -1270,7 +1193,7 @@ function BlockRenderer({ node, path }) {
1270
1193
  }
1271
1194
  function renderBlocks(nodes, basePath) {
1272
1195
  return nodes.map(
1273
- (node, i) => React3.createElement(BlockRenderer, {
1196
+ (node, i) => React2.createElement(BlockRenderer, {
1274
1197
  key: node.id ?? `${node.type}-${i}`,
1275
1198
  node,
1276
1199
  // POSITIONAL, deliberately. `[#id]` is the reorder-stable form
@@ -2266,9 +2189,9 @@ var app_manifest_schema_default = {
2266
2189
  }
2267
2190
  }
2268
2191
  };
2269
- var ManifestContext = React3.createContext(null);
2192
+ var ManifestContext = React2.createContext(null);
2270
2193
  function useManifest() {
2271
- return React3.useContext(ManifestContext);
2194
+ return React2.useContext(ManifestContext);
2272
2195
  }
2273
2196
  function defineApp(manifest) {
2274
2197
  const full = {
@@ -2300,10 +2223,10 @@ function renderApp(input, opts = {}) {
2300
2223
  `Scaffold "${surface.scaffold}" is not registered. Call renderApp from the package that provides it (e.g. @fayz-ai/admin, @fayz-ai/portal, @fayz-ai/storefront) or call its register*Scaffold() first.`
2301
2224
  );
2302
2225
  }
2303
- return React3.createElement(
2226
+ return React2.createElement(
2304
2227
  ManifestContext.Provider,
2305
2228
  { value: manifest },
2306
- React3.createElement(Scaffold, { manifest, surface: surfaceName })
2229
+ React2.createElement(Scaffold, { manifest, surface: surfaceName })
2307
2230
  );
2308
2231
  }
2309
2232
  var MAX_ENTRIES = 20;
@@ -2550,6 +2473,6 @@ function createVendorReporter(client2) {
2550
2473
  };
2551
2474
  }
2552
2475
 
2553
- export { APP_ERROR_EVENT, BLOCK_PATH_ATTRIBUTE, BLOCK_TYPE_ATTRIBUTE, BlockChildren, BlockErrorBoundary, BlockRenderer, COUNTRIES, CURRENT_MANIFEST_VERSION, DATA_CHANGED_EVENT, DEFAULT_COUNTRY, EVENT_LOG_TABLE, MESSAGE_TEMPLATES_TABLE, MIN_QUERY_LENGTH, WidgetZone, absoluteUrl, app_manifest_schema_default as appManifestSchema, applySeo, blockEditorMode, breadcrumbJsonLd, buildCSV, buildSeoTags, clearErrorReporters, clearEventSinks, clearMessageDefaults, clearPostalCache, clearSearchCache, computeContractHash, createEventBus, createSafeDataProvider, createVendorReporter, createViaCepProvider, defineApp, digitsOf, downloadCSV, emitDataChanged, emitDomainEvent, eventBus, exportCSV, foldText, foldWithMap, formatCurrency, formatDate, formatDateTime, formatPostalCode, getActiveLocale, getBlockErrorVisibility, getCountry, getDefaultCurrency, getEventsWithoutMessages, getMessageDefaults, getPostalLookupProvider, highlightRanges, installGlobalErrorHandlers, isSearchIndexAvailable, isValidPostalCode, loadEventRuns, loadMessageOverrides, lookupPostalCode, maskDigitCount, maskPhone, matchesDataChange, migrateManifest, navHistoryBack, normalizePostalCode, normalizeQuery, onDomainEvent, onDomainEvents, organizationJsonLd, recordEventRun, recordNavigation, registerErrorReporter, registerEventSink, registerManifestMigration, registerMessageDefaults, renderApp, renderBlocks, renderMessageTemplate, reportAppError, resetErrorDedupe, resolveBackendEnv, resolveMessage, resolveMessages, routeModule, sampleEventPayload, scoreCandidate, searchEverything, seoOrigin, serializeManifest, serializeManifestWithHash, setBlockEditorMode, setBlockErrorVisibility, setDefaultCurrency, setPostalLookupProvider, setSearchIndexAvailable, similarity, startEventLog, unmaskPhone, useBlockPath, useDataChanged, useManifest, useNavHistoryStore, useNavReferrer, useOnEvent, useSeo, validateManifest };
2476
+ export { APP_ERROR_EVENT, BLOCK_PATH_ATTRIBUTE, BLOCK_TYPE_ATTRIBUTE, BlockChildren, BlockErrorBoundary, BlockRenderer, COUNTRIES, CURRENT_MANIFEST_VERSION, DEFAULT_COUNTRY, EVENT_LOG_TABLE, MESSAGE_TEMPLATES_TABLE, MIN_QUERY_LENGTH, WidgetZone, absoluteUrl, app_manifest_schema_default as appManifestSchema, applySeo, blockEditorMode, breadcrumbJsonLd, buildCSV, buildSeoTags, clearErrorReporters, clearEventSinks, clearMessageDefaults, clearPostalCache, clearSearchCache, computeContractHash, createSafeDataProvider, createVendorReporter, createViaCepProvider, defineApp, digitsOf, downloadCSV, emitDomainEvent, exportCSV, foldText, foldWithMap, formatCurrency, formatDate, formatDateTime, formatPostalCode, getActiveLocale, getBlockErrorVisibility, getCountry, getDefaultCurrency, getEventsWithoutMessages, getMessageDefaults, getPostalLookupProvider, highlightRanges, installGlobalErrorHandlers, isSearchIndexAvailable, isValidPostalCode, loadEventRuns, loadMessageOverrides, lookupPostalCode, maskDigitCount, maskPhone, migrateManifest, navHistoryBack, normalizePostalCode, normalizeQuery, onDomainEvent, onDomainEvents, organizationJsonLd, recordEventRun, recordNavigation, registerErrorReporter, registerEventSink, registerManifestMigration, registerMessageDefaults, renderApp, renderBlocks, renderMessageTemplate, reportAppError, resetErrorDedupe, resolveBackendEnv, resolveMessage, resolveMessages, routeModule, sampleEventPayload, scoreCandidate, searchEverything, seoOrigin, serializeManifest, serializeManifestWithHash, setBlockEditorMode, setBlockErrorVisibility, setDefaultCurrency, setPostalLookupProvider, setSearchIndexAvailable, similarity, startEventLog, unmaskPhone, useBlockPath, useManifest, useNavHistoryStore, useNavReferrer, useOnEvent, useSeo, validateManifest };
2554
2477
  //# sourceMappingURL=index.js.map
2555
2478
  //# sourceMappingURL=index.js.map