@fayz-ai/core 0.9.0 → 0.11.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 (218) hide show
  1. package/README.md +2 -2
  2. package/dist/access/index.js.map +1 -1
  3. package/dist/chunk-BEGXYHS4.js +566 -0
  4. package/dist/chunk-BEGXYHS4.js.map +1 -0
  5. package/dist/chunk-ED6NBH6U.js +348 -0
  6. package/dist/chunk-ED6NBH6U.js.map +1 -0
  7. package/dist/chunk-EWKX4VUM.js +429 -0
  8. package/dist/chunk-EWKX4VUM.js.map +1 -0
  9. package/dist/chunk-LARZWDHA.js +319 -0
  10. package/dist/chunk-LARZWDHA.js.map +1 -0
  11. package/dist/chunk-OXQGRJZT.js +125 -0
  12. package/dist/chunk-OXQGRJZT.js.map +1 -0
  13. package/dist/chunk-RRYFXUQX.js +1247 -0
  14. package/dist/chunk-RRYFXUQX.js.map +1 -0
  15. package/dist/{chunk-5RJVUC6J.js → chunk-TDI6F6PT.js} +373 -25
  16. package/dist/chunk-TDI6F6PT.js.map +1 -0
  17. package/dist/{chunk-V2MSAUHO.js → chunk-UVKH6RDX.js} +211 -335
  18. package/dist/chunk-UVKH6RDX.js.map +1 -0
  19. package/dist/chunk-V53GR4UT.js +289 -0
  20. package/dist/chunk-V53GR4UT.js.map +1 -0
  21. package/dist/connector-runtime/index.d.ts +15 -0
  22. package/dist/connector-runtime/index.d.ts.map +1 -0
  23. package/dist/connector-runtime/index.js +3 -0
  24. package/dist/connector-runtime/index.js.map +1 -0
  25. package/dist/data/archetype.d.ts.map +1 -1
  26. package/dist/data/backend-env.d.ts +38 -0
  27. package/dist/data/backend-env.d.ts.map +1 -0
  28. package/dist/data/bulk.d.ts +24 -0
  29. package/dist/data/bulk.d.ts.map +1 -1
  30. package/dist/data/cached.d.ts.map +1 -1
  31. package/dist/data/custom-fields.d.ts +5 -0
  32. package/dist/data/custom-fields.d.ts.map +1 -0
  33. package/dist/data/index.d.ts +2 -1
  34. package/dist/data/index.d.ts.map +1 -1
  35. package/dist/data/index.js +3 -1
  36. package/dist/data/mock.d.ts.map +1 -1
  37. package/dist/data/platform-api.d.ts.map +1 -1
  38. package/dist/data/resolve.d.ts.map +1 -1
  39. package/dist/data/supabase.d.ts.map +1 -1
  40. package/dist/data/types.d.ts +8 -0
  41. package/dist/data/types.d.ts.map +1 -1
  42. package/dist/entity/events.d.ts +14 -0
  43. package/dist/entity/events.d.ts.map +1 -0
  44. package/dist/events/envelope.d.ts +31 -0
  45. package/dist/events/envelope.d.ts.map +1 -0
  46. package/dist/events/index.d.ts +4 -0
  47. package/dist/events/index.d.ts.map +1 -1
  48. package/dist/events/log.d.ts +44 -0
  49. package/dist/events/log.d.ts.map +1 -0
  50. package/dist/events/types.d.ts +40 -0
  51. package/dist/events/types.d.ts.map +1 -0
  52. package/dist/fields/store.d.ts +45 -0
  53. package/dist/fields/store.d.ts.map +1 -0
  54. package/dist/i18n/index.d.ts +10 -0
  55. package/dist/i18n/index.d.ts.map +1 -1
  56. package/dist/i18n/index.js +1 -1
  57. package/dist/i18n/shell-translations.en.d.ts.map +1 -1
  58. package/dist/i18n/shell-translations.pt-br.d.ts.map +1 -1
  59. package/dist/index.d.ts +45 -21
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +543 -56
  62. package/dist/index.js.map +1 -1
  63. package/dist/integrations/events.d.ts +7 -0
  64. package/dist/integrations/events.d.ts.map +1 -0
  65. package/dist/integrations/index.d.ts +533 -29
  66. package/dist/integrations/index.d.ts.map +1 -1
  67. package/dist/integrations/index.js +3 -1
  68. package/dist/integrations/permissions.d.ts +132 -0
  69. package/dist/integrations/permissions.d.ts.map +1 -0
  70. package/dist/integrations/request.d.ts +170 -0
  71. package/dist/integrations/request.d.ts.map +1 -0
  72. package/dist/integrations/runtime-token.d.ts +33 -0
  73. package/dist/integrations/runtime-token.d.ts.map +1 -0
  74. package/dist/integrations/runtime.d.ts +398 -0
  75. package/dist/integrations/runtime.d.ts.map +1 -0
  76. package/dist/integrations/settings.d.ts +102 -0
  77. package/dist/integrations/settings.d.ts.map +1 -0
  78. package/dist/integrations/store.d.ts +145 -0
  79. package/dist/integrations/store.d.ts.map +1 -0
  80. package/dist/{address/index.d.ts → lib/address.d.ts} +1 -1
  81. package/dist/{address/index.d.ts.map → lib/address.d.ts.map} +1 -1
  82. package/dist/{phone/index.d.ts → lib/phone.d.ts} +1 -1
  83. package/dist/lib/phone.d.ts.map +1 -0
  84. package/dist/{seo/index.d.ts → lib/seo.d.ts} +18 -1
  85. package/dist/lib/seo.d.ts.map +1 -0
  86. package/dist/{tenant/index.d.ts → lib/tenant.d.ts} +1 -1
  87. package/dist/lib/tenant.d.ts.map +1 -0
  88. package/dist/manifest/index.d.ts +1 -1
  89. package/dist/manifest/index.d.ts.map +1 -1
  90. package/dist/messaging/index.d.ts +3 -0
  91. package/dist/messaging/index.d.ts.map +1 -0
  92. package/dist/messaging/registry.d.ts +35 -0
  93. package/dist/messaging/registry.d.ts.map +1 -0
  94. package/dist/messaging/types.d.ts +67 -0
  95. package/dist/messaging/types.d.ts.map +1 -0
  96. package/dist/plugin/index.js +3 -1
  97. package/dist/plugin/runtime.d.ts +17 -0
  98. package/dist/plugin/runtime.d.ts.map +1 -1
  99. package/dist/registry/block-catalog.d.ts +78 -0
  100. package/dist/registry/block-catalog.d.ts.map +1 -0
  101. package/dist/registry/block-constraints.d.ts +64 -0
  102. package/dist/registry/block-constraints.d.ts.map +1 -0
  103. package/dist/registry/block-schema.d.ts +69 -0
  104. package/dist/registry/block-schema.d.ts.map +1 -0
  105. package/dist/registry/blocks.d.ts +84 -0
  106. package/dist/registry/blocks.d.ts.map +1 -0
  107. package/dist/registry/entities.d.ts +179 -0
  108. package/dist/registry/entities.d.ts.map +1 -0
  109. package/dist/registry/extension-points.d.ts +117 -0
  110. package/dist/registry/extension-points.d.ts.map +1 -0
  111. package/dist/registry/handles.d.ts +41 -0
  112. package/dist/registry/handles.d.ts.map +1 -0
  113. package/dist/registry/index.d.ts +41 -41
  114. package/dist/registry/index.d.ts.map +1 -1
  115. package/dist/registry/loaders.d.ts +55 -0
  116. package/dist/registry/loaders.d.ts.map +1 -0
  117. package/dist/registry/registry-class.d.ts +157 -0
  118. package/dist/registry/registry-class.d.ts.map +1 -0
  119. package/dist/registry/schema-check.d.ts +14 -0
  120. package/dist/registry/schema-check.d.ts.map +1 -0
  121. package/dist/router/index.d.ts +78 -1
  122. package/dist/router/index.d.ts.map +1 -1
  123. package/dist/router/index.js +1 -1
  124. package/dist/{shell-translations.pt-br-2GWRQRRP.js → shell-translations.pt-br-BM5ZFSKJ.js} +72 -3
  125. package/dist/shell-translations.pt-br-BM5ZFSKJ.js.map +1 -0
  126. package/dist/telemetry/errors.d.ts +87 -0
  127. package/dist/telemetry/errors.d.ts.map +1 -0
  128. package/dist/testing/index.js +4 -1
  129. package/dist/{testing/index.d.ts → testing.d.ts} +5 -3
  130. package/dist/testing.d.ts.map +1 -0
  131. package/dist/types/analytics.d.ts +213 -0
  132. package/dist/types/analytics.d.ts.map +1 -0
  133. package/dist/types/crud.d.ts +37 -3
  134. package/dist/types/crud.d.ts.map +1 -1
  135. package/dist/types/plugins.d.ts +138 -1
  136. package/dist/types/plugins.d.ts.map +1 -1
  137. package/package.json +9 -17
  138. package/dist/blocks/index.d.ts +0 -25
  139. package/dist/blocks/index.d.ts.map +0 -1
  140. package/dist/chunk-5RJVUC6J.js.map +0 -1
  141. package/dist/chunk-L4TLMYGC.js +0 -42
  142. package/dist/chunk-L4TLMYGC.js.map +0 -1
  143. package/dist/chunk-V2MSAUHO.js.map +0 -1
  144. package/dist/chunk-X5THHG6T.js +0 -77
  145. package/dist/chunk-X5THHG6T.js.map +0 -1
  146. package/dist/chunk-Y2C2FBQP.js +0 -35
  147. package/dist/chunk-Y2C2FBQP.js.map +0 -1
  148. package/dist/chunk-YH25Y4FW.js +0 -311
  149. package/dist/chunk-YH25Y4FW.js.map +0 -1
  150. package/dist/phone/index.d.ts.map +0 -1
  151. package/dist/seo/index.d.ts.map +0 -1
  152. package/dist/shell-translations.pt-br-2GWRQRRP.js.map +0 -1
  153. package/dist/tenant/index.d.ts.map +0 -1
  154. package/dist/testing/index.d.ts.map +0 -1
  155. package/src/access/denial.ts +0 -33
  156. package/src/access/engine.test.ts +0 -48
  157. package/src/access/engine.ts +0 -136
  158. package/src/access/index.ts +0 -14
  159. package/src/access/limits.ts +0 -18
  160. package/src/address/index.ts +0 -188
  161. package/src/app/render.tsx +0 -69
  162. package/src/blocks/index.tsx +0 -68
  163. package/src/data/archetype.ts +0 -255
  164. package/src/data/bulk.ts +0 -35
  165. package/src/data/cached.ts +0 -55
  166. package/src/data/count.test.ts +0 -152
  167. package/src/data/count.ts +0 -131
  168. package/src/data/filters.test.ts +0 -70
  169. package/src/data/filters.ts +0 -90
  170. package/src/data/index.ts +0 -11
  171. package/src/data/mock.ts +0 -90
  172. package/src/data/platform-api.ts +0 -209
  173. package/src/data/refresh.ts +0 -115
  174. package/src/data/resolve.ts +0 -126
  175. package/src/data/supabase.ts +0 -230
  176. package/src/data/types.ts +0 -50
  177. package/src/entity/index.ts +0 -2
  178. package/src/entity/registry.ts +0 -49
  179. package/src/events/index.tsx +0 -82
  180. package/src/i18n/index.ts +0 -476
  181. package/src/i18n/shell-translations.en.ts +0 -875
  182. package/src/i18n/shell-translations.pt-br.ts +0 -873
  183. package/src/index.ts +0 -217
  184. package/src/integrations/index.ts +0 -237
  185. package/src/lib/cache.ts +0 -118
  186. package/src/lib/csv.ts +0 -54
  187. package/src/lib/format.ts +0 -58
  188. package/src/manifest/app-manifest.schema.json +0 -676
  189. package/src/manifest/index.ts +0 -518
  190. package/src/manifest/serialize.ts +0 -52
  191. package/src/phone/index.ts +0 -85
  192. package/src/plugin/createSafeDataProvider.ts +0 -30
  193. package/src/plugin/index.ts +0 -1
  194. package/src/plugin/runtime.ts +0 -331
  195. package/src/registry/index.ts +0 -163
  196. package/src/router/history.ts +0 -86
  197. package/src/router/index.ts +0 -29
  198. package/src/runtime/index.ts +0 -15
  199. package/src/runtime/oauth.ts +0 -219
  200. package/src/search/engine.ts +0 -559
  201. package/src/search/index.ts +0 -25
  202. package/src/search/text.ts +0 -206
  203. package/src/search/types.ts +0 -75
  204. package/src/seo/index.ts +0 -128
  205. package/src/tenant/index.ts +0 -38
  206. package/src/testing/index.ts +0 -116
  207. package/src/types/auth.ts +0 -41
  208. package/src/types/billing.ts +0 -39
  209. package/src/types/crud.ts +0 -184
  210. package/src/types/entities.ts +0 -142
  211. package/src/types/entitlements.ts +0 -45
  212. package/src/types/i18n.ts +0 -7
  213. package/src/types/index.ts +0 -11
  214. package/src/types/org.ts +0 -137
  215. package/src/types/payment.ts +0 -44
  216. package/src/types/permissions.ts +0 -32
  217. package/src/types/plugins.ts +0 -480
  218. package/src/types/theme.ts +0 -8
package/dist/index.js CHANGED
@@ -1,13 +1,17 @@
1
- export { connectorDirection, connectorPlanes, preferredPlane, withAfterHooks } from './chunk-L4TLMYGC.js';
2
- export { PluginContractError, assertConnectorContract, assertPluginManifestContract } from './chunk-X5THHG6T.js';
3
- import { getActiveTenantId, globalCache, getSupabaseClientOptional, resolveDataProvider } from './chunk-V2MSAUHO.js';
4
- export { applyRangeToQuery, bulkCreate, clearGlobalCache, countByTenant, createArchetypeProvider, createCacheStore, createFayzApiProvider, createMockProvider, createSupabaseProvider, getActiveTenantId, getSupabaseClientOptional, globalCache, invalidateCount, isFilterObject, matchesRange, parseRangeFilter, resolveDataProvider, setActiveTenantId, setGlobalSupabaseClient, stableKey, subscribeActiveTenant, useActiveTenantId, withCache } from './chunk-V2MSAUHO.js';
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';
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';
8
+ import { getBlock, checkNodePlacement, getScaffold } from './chunk-RRYFXUQX.js';
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
+ 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';
5
11
  export { clearEntityRegistry, deriveEntityKey, getAllEntities, getEntityByKey, registerEntity } from './chunk-CU64QI4A.js';
6
- import { getBlock, getScaffold } from './chunk-YH25Y4FW.js';
7
- export { PLUGIN_API_VERSION, PluginRuntimeProvider, Registry, blockRegistry, componentRegistry, definePlugin, getBlock, getComponent, getDashboardWidgets, getMetric, getPage, getPlugin, getPluginFactory, getScaffold, getWidgetsForZone, isCustomId, listBlocks, listMetrics, listPluginFactories, listPlugins, metricRegistry, pageRegistry, pluginFactoryRegistry, pluginRegistry, registerBlock, registerComponent, registerMetric, registerPage, registerPlugin, registerPluginFactory, registerScaffold, resolvePluginComponent, resolvePluginRuntime, scaffoldRegistry, useConnectorsForPlugin, usePluginRuntime, usePluginRuntimeOptional } from './chunk-YH25Y4FW.js';
8
- import { getCurrentLocale } from './chunk-5RJVUC6J.js';
9
- export { I18nProvider, coreTranslations, getCurrentLocale, mergeTranslations, preloadLocale, registerTranslations, setCurrentLocale, setLocaleStore, useI18nConfig, useTranslation } from './chunk-5RJVUC6J.js';
10
- export { hashRouterAdapter, windowRouterAdapter } from './chunk-Y2C2FBQP.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';
14
+ export { defaultRouterAdapter, hashRouterAdapter, historyRouterAdapter, hostRouterAdapter, staticRouterAdapter, windowRouterAdapter } from './chunk-OXQGRJZT.js';
11
15
  export { FayzRuntimeError, createFayzRuntimeClient } from './chunk-7RTUHSKY.js';
12
16
  import * as React3 from 'react';
13
17
  import { useEffect } from 'react';
@@ -25,6 +29,162 @@ var WidgetZone = {
25
29
  SETTINGS_AFTER: "settings.after",
26
30
  FLOATING: "shell.floating"
27
31
  };
32
+
33
+ // src/data/backend-env.ts
34
+ function str(value) {
35
+ return typeof value === "string" && value.length > 0 ? value : void 0;
36
+ }
37
+ function resolveBackendEnv(options = {}) {
38
+ const env = options.env ?? (import.meta.env ?? {});
39
+ const url = str(env.VITE_SUPABASE_URL);
40
+ const key = str(env.VITE_SUPABASE_PUBLISHABLE_KEY) ?? str(env.VITE_SUPABASE_ANON_KEY);
41
+ const flag = env.VITE_SUPABASE_ENABLED;
42
+ const flagSet = flag !== void 0 && flag !== "";
43
+ const enabledByFlag = flag === true || flag === "true";
44
+ let live;
45
+ if (options.force) live = options.force === "live";
46
+ else if (flagSet) live = enabledByFlag && Boolean(url && key);
47
+ else live = Boolean(url && key);
48
+ return {
49
+ live,
50
+ supabaseUrl: live ? url : void 0,
51
+ supabaseAnonKey: live ? key : void 0,
52
+ adapter: live ? "supabase" : "mock"
53
+ };
54
+ }
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
28
188
  function createEventBus() {
29
189
  const handlers = /* @__PURE__ */ new Map();
30
190
  const bus = {
@@ -86,11 +246,11 @@ function matchesDataChange(match, payload) {
86
246
  if (match.archetype && payload.archetype && match.archetype === payload.archetype) return true;
87
247
  return !match.table && !match.entityKey && !match.archetype;
88
248
  }
89
- var pending = [];
249
+ var pending2 = [];
90
250
  var flushTimer = null;
91
251
  function flush() {
92
- const batch = pending;
93
- pending = [];
252
+ const batch = pending2;
253
+ pending2 = [];
94
254
  flushTimer = null;
95
255
  for (const payload of batch) eventBus.emit(DATA_CHANGED_EVENT, payload);
96
256
  }
@@ -103,7 +263,7 @@ function emitDataChanged(payload = {}) {
103
263
  } else {
104
264
  globalCache.clear();
105
265
  }
106
- pending.push({ op: "unknown", source: "agent", ...payload });
266
+ pending2.push({ op: "unknown", source: "agent", ...payload });
107
267
  if (flushTimer) return;
108
268
  flushTimer = setTimeout(flush, 120);
109
269
  }
@@ -134,7 +294,7 @@ function createSafeDataProvider(makeSupabase, makeMock) {
134
294
  });
135
295
  }
136
296
 
137
- // src/phone/index.ts
297
+ // src/lib/phone.ts
138
298
  function flagOf(iso2) {
139
299
  return iso2.toUpperCase().replace(/[^A-Z]/g, "").split("").map((c) => String.fromCodePoint(127462 + c.charCodeAt(0) - 65)).join("");
140
300
  }
@@ -179,7 +339,7 @@ function maskDigitCount(mask) {
179
339
  return n;
180
340
  }
181
341
 
182
- // src/address/index.ts
342
+ // src/lib/address.ts
183
343
  function normalizePostalCode(value) {
184
344
  return (value || "").replace(/\D/g, "");
185
345
  }
@@ -296,23 +456,41 @@ function upsertLink(rel, href) {
296
456
  function clearManaged() {
297
457
  document.head.querySelectorAll(`[${MANAGED}]`).forEach((el) => el.remove());
298
458
  }
459
+ function buildSeoTags(config) {
460
+ const description = config.description ?? "";
461
+ const meta = [
462
+ { name: "description", content: description },
463
+ { property: "og:title", content: config.title },
464
+ { property: "og:description", content: description },
465
+ { property: "og:type", content: config.type ?? "website" },
466
+ { name: "twitter:card", content: config.image ? "summary_large_image" : "summary" },
467
+ { name: "twitter:title", content: config.title },
468
+ { name: "twitter:description", content: description }
469
+ ];
470
+ if (config.canonical) meta.push({ property: "og:url", content: config.canonical });
471
+ if (config.image) {
472
+ meta.push({ property: "og:image", content: config.image });
473
+ meta.push({ name: "twitter:image", content: config.image });
474
+ }
475
+ if (config.siteName) meta.push({ property: "og:site_name", content: config.siteName });
476
+ return {
477
+ title: config.title,
478
+ meta: meta.filter((m) => m.content !== ""),
479
+ links: config.canonical ? [{ rel: "canonical", href: config.canonical }] : [],
480
+ jsonLd: config.jsonLd ?? []
481
+ };
482
+ }
299
483
  function applySeo(config) {
300
484
  if (typeof document === "undefined") return;
485
+ const tags = buildSeoTags(config);
301
486
  clearManaged();
302
- document.title = config.title;
303
- upsertMeta("name", "description", config.description ?? "");
304
- if (config.canonical) upsertLink("canonical", config.canonical);
305
- upsertMeta("property", "og:title", config.title);
306
- upsertMeta("property", "og:description", config.description ?? "");
307
- upsertMeta("property", "og:type", config.type === "article" ? "article" : "website");
308
- if (config.canonical) upsertMeta("property", "og:url", config.canonical);
309
- if (config.image) upsertMeta("property", "og:image", config.image);
310
- if (config.siteName) upsertMeta("property", "og:site_name", config.siteName);
311
- upsertMeta("name", "twitter:card", config.image ? "summary_large_image" : "summary");
312
- upsertMeta("name", "twitter:title", config.title);
313
- upsertMeta("name", "twitter:description", config.description ?? "");
314
- if (config.image) upsertMeta("name", "twitter:image", config.image);
315
- for (const obj of config.jsonLd ?? []) {
487
+ document.title = tags.title;
488
+ for (const tag of tags.meta) {
489
+ if (tag.name) upsertMeta("name", tag.name, tag.content);
490
+ else if (tag.property) upsertMeta("property", tag.property, tag.content);
491
+ }
492
+ for (const link of tags.links) upsertLink(link.rel, link.href);
493
+ for (const obj of tags.jsonLd) {
316
494
  const script = document.createElement("script");
317
495
  script.type = "application/ld+json";
318
496
  script.setAttribute(MANAGED, "");
@@ -395,11 +573,11 @@ function formatDateTime(value) {
395
573
  // src/lib/csv.ts
396
574
  function escapeCSVField(value) {
397
575
  if (value == null) return "";
398
- const str = String(value);
399
- if (str.includes(",") || str.includes('"') || str.includes("\n")) {
400
- return `"${str.replace(/"/g, '""')}"`;
576
+ const str2 = String(value);
577
+ if (str2.includes(",") || str2.includes('"') || str2.includes("\n")) {
578
+ return `"${str2.replace(/"/g, '""')}"`;
401
579
  }
402
- return str;
580
+ return str2;
403
581
  }
404
582
  function buildCSV(columns, rows) {
405
583
  const header = columns.map((c) => escapeCSVField(c.label)).join(",");
@@ -780,11 +958,11 @@ function isMissingFunction(error) {
780
958
  return message.includes(RPC_NAME) && (message.includes("does not exist") || message.includes("not find"));
781
959
  }
782
960
  async function searchViaIndex(query, targets, perTarget, limit) {
783
- const client = getSupabaseClientOptional();
961
+ const client2 = getSupabaseClientOptional();
784
962
  const tenantId = getActiveTenantId();
785
- if (!client || !tenantId) return { hits: [], ok: false };
963
+ if (!client2 || !tenantId) return { hits: [], ok: false };
786
964
  const byKey = new Map(targets.map((t) => [t.key, t]));
787
- const { data, error } = await client.rpc(RPC_NAME, {
965
+ const { data, error } = await client2.rpc(RPC_NAME, {
788
966
  p_query: query.raw,
789
967
  p_tenant_id: tenantId,
790
968
  p_entity_keys: targets.map((t) => t.key),
@@ -895,12 +1073,12 @@ async function searchViaScan(query, targets, perTarget, onProgress) {
895
1073
  return { hits: second.hits, failed: [.../* @__PURE__ */ new Set([...first.failed, ...second.failed])] };
896
1074
  }
897
1075
  async function searchEverything(rawQuery, options) {
898
- const started = Date.now();
1076
+ const started2 = Date.now();
899
1077
  const query = normalizeQuery(rawQuery);
900
1078
  const targets = options.targets;
901
1079
  const limit = options.limit ?? DEFAULT_LIMIT;
902
1080
  const perTarget = options.perTarget ?? DEFAULT_PER_TARGET;
903
- const empty = (via2) => assemble(rawQuery, [], targets, { via: via2, failed: [], elapsedMs: Date.now() - started, perTarget, limit });
1081
+ const empty = (via2) => assemble(rawQuery, [], targets, { via: via2, failed: [], elapsedMs: Date.now() - started2, perTarget, limit });
904
1082
  if (query.folded.length < MIN_QUERY_LENGTH || targets.length === 0) return empty("cache");
905
1083
  const scope = scopeKey(targets);
906
1084
  const exact = cacheGet(scope, query.folded);
@@ -908,7 +1086,7 @@ async function searchEverything(rawQuery, options) {
908
1086
  return assemble(rawQuery, exact.hits, targets, {
909
1087
  via: "cache",
910
1088
  failed: [],
911
- elapsedMs: Date.now() - started,
1089
+ elapsedMs: Date.now() - started2,
912
1090
  perTarget,
913
1091
  limit
914
1092
  });
@@ -927,7 +1105,7 @@ async function searchEverything(rawQuery, options) {
927
1105
  options.onPartial(assemble(rawQuery, rescored, targets, {
928
1106
  via: "cache",
929
1107
  failed: [],
930
- elapsedMs: Date.now() - started,
1108
+ elapsedMs: Date.now() - started2,
931
1109
  perTarget,
932
1110
  limit,
933
1111
  partial: true
@@ -952,7 +1130,7 @@ async function searchEverything(rawQuery, options) {
952
1130
  const scanned = await searchViaScan(query, targets, perTarget, emit ? (running) => emit(assemble(rawQuery, running, targets, {
953
1131
  via: "scan",
954
1132
  failed: [],
955
- elapsedMs: Date.now() - started,
1133
+ elapsedMs: Date.now() - started2,
956
1134
  perTarget,
957
1135
  limit,
958
1136
  partial: true
@@ -964,7 +1142,7 @@ async function searchEverything(rawQuery, options) {
964
1142
  const result = assemble(rawQuery, hits, targets, {
965
1143
  via,
966
1144
  failed,
967
- elapsedMs: Date.now() - started,
1145
+ elapsedMs: Date.now() - started2,
968
1146
  perTarget,
969
1147
  limit
970
1148
  });
@@ -978,37 +1156,142 @@ async function searchEverything(rawQuery, options) {
978
1156
  });
979
1157
  return result;
980
1158
  }
981
- function UnknownBlock({ type }) {
1159
+ var errorVisibility = null;
1160
+ function defaultVisibility() {
1161
+ try {
1162
+ return process.env.NODE_ENV !== "production" ? "visible" : "silent";
1163
+ } catch {
1164
+ return "silent";
1165
+ }
1166
+ }
1167
+ function setBlockErrorVisibility(visibility) {
1168
+ errorVisibility = visibility;
1169
+ }
1170
+ var editorMode = false;
1171
+ function setBlockEditorMode(enabled) {
1172
+ editorMode = enabled;
1173
+ }
1174
+ function blockEditorMode() {
1175
+ return editorMode;
1176
+ }
1177
+ var BLOCK_PATH_ATTRIBUTE = "data-fayz-block";
1178
+ var BLOCK_TYPE_ATTRIBUTE = "data-fayz-block-type";
1179
+ var BlockPathContext = React3.createContext("");
1180
+ function useBlockPath() {
1181
+ return React3.useContext(BlockPathContext);
1182
+ }
1183
+ function getBlockErrorVisibility() {
1184
+ return errorVisibility ?? defaultVisibility();
1185
+ }
1186
+ function BlockErrorCard({ title, detail }) {
982
1187
  return React3.createElement(
983
1188
  "div",
984
1189
  {
1190
+ "data-block-error": title,
985
1191
  style: {
986
- border: "1px dashed #c026d3",
987
- color: "#a21caf",
1192
+ border: "1px dashed #dc2626",
1193
+ color: "#b91c1c",
988
1194
  padding: "8px 12px",
989
1195
  font: "12px ui-monospace, monospace",
990
1196
  borderRadius: 6
991
1197
  }
992
1198
  },
993
- `Unknown block: "${type}"`
1199
+ title,
1200
+ detail ? React3.createElement("div", { style: { opacity: 0.8, marginTop: 4 } }, detail) : null
994
1201
  );
995
1202
  }
996
- function BlockRenderer({ node }) {
1203
+ function UnknownBlock({ type }) {
1204
+ if (getBlockErrorVisibility() === "silent") return null;
1205
+ return React3.createElement(BlockErrorCard, { title: `Unknown block: "${type}"` });
1206
+ }
1207
+ var BlockErrorBoundary = class extends React3.Component {
1208
+ constructor() {
1209
+ super(...arguments);
1210
+ this.state = { error: null };
1211
+ }
1212
+ static getDerivedStateFromError(error) {
1213
+ return { error };
1214
+ }
1215
+ componentDidCatch(error, info) {
1216
+ console.error(`[blocks] block "${this.props.blockType}" crashed while rendering:`, error, info.componentStack);
1217
+ }
1218
+ render() {
1219
+ if (!this.state.error) return this.props.children;
1220
+ if (getBlockErrorVisibility() === "silent") return null;
1221
+ return React3.createElement(BlockErrorCard, {
1222
+ title: `Block "${this.props.blockType}" crashed`,
1223
+ detail: this.state.error.message
1224
+ });
1225
+ }
1226
+ };
1227
+ var BlockAncestryContext = React3.createContext([]);
1228
+ function ConstraintViolation({ detail }) {
1229
+ if (getBlockErrorVisibility() === "silent") return null;
1230
+ return React3.createElement(BlockErrorCard, { title: "Misplaced block", detail });
1231
+ }
1232
+ var warnedViolations = /* @__PURE__ */ new Set();
1233
+ function BlockRenderer({ node, path }) {
1234
+ const ancestry = React3.useContext(BlockAncestryContext);
997
1235
  const Comp = getBlock(node.type);
998
- const childEls = node.children?.length ? node.children.map(
999
- (child, i) => React3.createElement(BlockRenderer, { key: child.id ?? `${child.type}-${i}`, node: child })
1000
- ) : null;
1001
1236
  if (!Comp) return React3.createElement(UnknownBlock, { type: node.type });
1002
- return React3.createElement(Comp, { ...node.props ?? {}, node }, childEls);
1237
+ const violations = checkNodePlacement(node.type, ancestry);
1238
+ if (violations.length > 0) {
1239
+ const message = violations.map((v) => v.detail).join("; ");
1240
+ if (!warnedViolations.has(message)) {
1241
+ warnedViolations.add(message);
1242
+ console.warn(`[blocks] ${message}`);
1243
+ }
1244
+ return React3.createElement(ConstraintViolation, { detail: violations[0].detail });
1245
+ }
1246
+ const childEls = node.children?.length ? renderBlocks(node.children, path ? `${path}.children` : void 0) : null;
1247
+ const rendered = React3.createElement(
1248
+ BlockAncestryContext.Provider,
1249
+ { value: ancestry.length ? [...ancestry, node.type] : [node.type] },
1250
+ React3.createElement(
1251
+ BlockErrorBoundary,
1252
+ { blockType: node.type },
1253
+ React3.createElement(Comp, { ...node.props ?? {}, node }, childEls)
1254
+ )
1255
+ );
1256
+ if (!editorMode || !path) return rendered;
1257
+ return React3.createElement(
1258
+ BlockPathContext.Provider,
1259
+ { value: path },
1260
+ React3.createElement(
1261
+ "div",
1262
+ {
1263
+ [BLOCK_PATH_ATTRIBUTE]: path,
1264
+ [BLOCK_TYPE_ATTRIBUTE]: node.type,
1265
+ style: { display: "contents" }
1266
+ },
1267
+ rendered
1268
+ )
1269
+ );
1003
1270
  }
1004
- function renderBlocks(nodes) {
1271
+ function renderBlocks(nodes, basePath) {
1005
1272
  return nodes.map(
1006
- (node, i) => React3.createElement(BlockRenderer, { key: node.id ?? `${node.type}-${i}`, node })
1273
+ (node, i) => React3.createElement(BlockRenderer, {
1274
+ key: node.id ?? `${node.type}-${i}`,
1275
+ node,
1276
+ // POSITIONAL, deliberately. `[#id]` is the reorder-stable form
1277
+ // store-change supports, and using it here looked obviously better — but
1278
+ // by the time a node reaches this function its `id` has been synthesized
1279
+ // (`${type}-${index}`) for every block the document did not name, and the
1280
+ // renderer cannot tell an authored id from a generated one. Emitting
1281
+ // `[#hero-0]` produced paths that resolve against nothing.
1282
+ //
1283
+ // The cost of positional is that a reorder invalidates an outstanding
1284
+ // path. That is bounded: a path is captured on click and spent on save,
1285
+ // and a document that names its blocks can be addressed by id by whoever
1286
+ // holds the document — which is the editor, not the renderer.
1287
+ path: basePath ? `${basePath}[${i}]` : void 0
1288
+ })
1007
1289
  );
1008
1290
  }
1009
1291
  function BlockChildren({ node }) {
1292
+ const path = useBlockPath();
1010
1293
  if (!node?.children?.length) return null;
1011
- return renderBlocks(node.children);
1294
+ return renderBlocks(node.children, path ? `${path}.children` : void 0);
1012
1295
  }
1013
1296
 
1014
1297
  // src/manifest/index.ts
@@ -2014,7 +2297,7 @@ function renderApp(input, opts = {}) {
2014
2297
  const Scaffold = getScaffold(surface.scaffold);
2015
2298
  if (!Scaffold) {
2016
2299
  throw new Error(
2017
- `Scaffold "${surface.scaffold}" is not registered. Call renderApp from the package that provides it (e.g. @fayz-ai/saas, @fayz-ai/portal, @fayz-ai/storefront) or call its register*Scaffold() first.`
2300
+ `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.`
2018
2301
  );
2019
2302
  }
2020
2303
  return React3.createElement(
@@ -2063,6 +2346,210 @@ function routeModule(path) {
2063
2346
  return path.replace(/^\/+/, "").split("/")[0] ?? "";
2064
2347
  }
2065
2348
 
2066
- export { BlockChildren, BlockRenderer, COUNTRIES, CURRENT_MANIFEST_VERSION, DATA_CHANGED_EVENT, DEFAULT_COUNTRY, MIN_QUERY_LENGTH, WidgetZone, absoluteUrl, app_manifest_schema_default as appManifestSchema, applySeo, breadcrumbJsonLd, buildCSV, clearPostalCache, clearSearchCache, computeContractHash, createEventBus, createSafeDataProvider, createViaCepProvider, defineApp, digitsOf, downloadCSV, emitDataChanged, eventBus, exportCSV, foldText, foldWithMap, formatCurrency, formatDate, formatDateTime, formatPostalCode, getActiveLocale, getCountry, getDefaultCurrency, getPostalLookupProvider, highlightRanges, isSearchIndexAvailable, isValidPostalCode, lookupPostalCode, maskDigitCount, maskPhone, matchesDataChange, migrateManifest, navHistoryBack, normalizePostalCode, normalizeQuery, organizationJsonLd, recordNavigation, registerManifestMigration, renderApp, renderBlocks, routeModule, scoreCandidate, searchEverything, seoOrigin, serializeManifest, serializeManifestWithHash, setDefaultCurrency, setPostalLookupProvider, setSearchIndexAvailable, similarity, unmaskPhone, useDataChanged, useManifest, useNavHistoryStore, useNavReferrer, useOnEvent, useSeo, validateManifest };
2349
+ // src/messaging/registry.ts
2350
+ var defaultsRegistry = /* @__PURE__ */ new Map();
2351
+ function registerMessageDefaults(defs) {
2352
+ for (const def of defs) defaultsRegistry.set(def.eventKey, def);
2353
+ }
2354
+ function getMessageDefaults() {
2355
+ return Array.from(defaultsRegistry.values());
2356
+ }
2357
+ function clearMessageDefaults() {
2358
+ defaultsRegistry.clear();
2359
+ }
2360
+ function renderMessageTemplate(text, values) {
2361
+ return text.replace(/\{\{\s*(\w+)\s*\}\}/g, (whole, key) => values[key] ?? whole);
2362
+ }
2363
+ function resolveMessages(overrides, events) {
2364
+ const byKey = new Map(overrides.map((o) => [`${o.eventKey}:${o.channel}`, o]));
2365
+ const byEvent = new Map(events.map((e) => [e.name, e]));
2366
+ const out = [];
2367
+ for (const def of getMessageDefaults()) {
2368
+ const event = byEvent.get(def.eventKey);
2369
+ if (!event) continue;
2370
+ const placeholders = (event.fields ?? []).map((f) => `{{${f.name}}}`);
2371
+ for (const channel of def.channels) {
2372
+ const fallback = def.defaults[channel];
2373
+ if (!fallback) continue;
2374
+ const override = byKey.get(`${def.eventKey}:${channel}`) ?? null;
2375
+ out.push({
2376
+ event,
2377
+ kind: def.kind,
2378
+ channel,
2379
+ override,
2380
+ enabled: override?.enabled ?? def.defaultEnabled?.[channel] ?? false,
2381
+ subject: override?.subject ?? fallback.subject ?? "",
2382
+ body: override?.body ?? fallback.body,
2383
+ customized: Boolean(override?.subject || override?.body),
2384
+ placeholders
2385
+ });
2386
+ }
2387
+ }
2388
+ return out;
2389
+ }
2390
+ function resolveMessage(eventKey, channel, overrides, events) {
2391
+ return resolveMessages(overrides, events).find((m) => m.event.name === eventKey && m.channel === channel) ?? null;
2392
+ }
2393
+ function getEventsWithoutMessages(events) {
2394
+ return events.filter((e) => !defaultsRegistry.has(e.name));
2395
+ }
2396
+ var MESSAGE_TEMPLATES_TABLE = "plg_automations_templates";
2397
+ async function loadMessageOverrides(tenantId) {
2398
+ const client2 = getSupabaseClientOptional();
2399
+ if (!client2) return [];
2400
+ try {
2401
+ let q = client2.from(MESSAGE_TEMPLATES_TABLE).select("*");
2402
+ if (tenantId) q = q.eq("tenant_id", tenantId);
2403
+ const { data, error } = await q;
2404
+ if (error) throw error;
2405
+ return (data ?? []).map((row) => ({
2406
+ id: row.id,
2407
+ tenantId: row.tenant_id,
2408
+ eventKey: row.event_key,
2409
+ channel: row.channel ?? "email",
2410
+ enabled: row.enabled ?? null,
2411
+ subject: row.subject || null,
2412
+ body: row.body || null,
2413
+ name: row.name || null,
2414
+ updatedAt: row.updated_at ?? row.created_at
2415
+ }));
2416
+ } catch (err) {
2417
+ console.warn("[messaging] could not load overrides; using defaults", err);
2418
+ return [];
2419
+ }
2420
+ }
2421
+
2422
+ // src/telemetry/errors.ts
2423
+ var APP_ERROR_EVENT = "app.error";
2424
+ var reporters = /* @__PURE__ */ new Set();
2425
+ function registerErrorReporter(reporter) {
2426
+ reporters.add(reporter);
2427
+ return () => {
2428
+ reporters.delete(reporter);
2429
+ };
2430
+ }
2431
+ function clearErrorReporters() {
2432
+ reporters.clear();
2433
+ }
2434
+ function makeErrorId() {
2435
+ const bytes = globalThis.crypto?.getRandomValues?.(new Uint8Array(3));
2436
+ const hex = bytes ? Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("") : Math.floor(Math.random() * 16777215).toString(16).padStart(6, "0");
2437
+ return `ERR-${hex.toUpperCase()}`;
2438
+ }
2439
+ function toError(value) {
2440
+ if (value instanceof Error) {
2441
+ return { name: value.name, message: value.message, stack: value.stack };
2442
+ }
2443
+ if (typeof value === "string") return { name: "Error", message: value };
2444
+ try {
2445
+ return { name: "Error", message: JSON.stringify(value) ?? String(value) };
2446
+ } catch {
2447
+ return { name: "Error", message: String(value) };
2448
+ }
2449
+ }
2450
+ var DEDUPE_WINDOW_MS = 5e3;
2451
+ var recent = /* @__PURE__ */ new Map();
2452
+ function isDuplicate(signature) {
2453
+ const now = Date.now();
2454
+ for (const [key, at] of recent) {
2455
+ if (now - at > DEDUPE_WINDOW_MS) recent.delete(key);
2456
+ }
2457
+ const seen = recent.get(signature);
2458
+ recent.set(signature, now);
2459
+ return seen !== void 0 && now - seen < DEDUPE_WINDOW_MS;
2460
+ }
2461
+ function resetErrorDedupe() {
2462
+ recent.clear();
2463
+ }
2464
+ function reportAppError(error, context = {}) {
2465
+ const { name, message, stack } = toError(error);
2466
+ const report = {
2467
+ id: makeErrorId(),
2468
+ name,
2469
+ message,
2470
+ stack,
2471
+ source: context.source ?? "manual",
2472
+ route: context.route ?? null,
2473
+ location: context.location ?? (typeof window !== "undefined" ? window.location.href : null),
2474
+ componentStack: context.componentStack ?? null,
2475
+ tenantId: context.tenantId ?? getActiveTenantId() ?? null,
2476
+ userId: context.userId ?? null,
2477
+ occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
2478
+ userAgent: typeof navigator !== "undefined" ? navigator.userAgent : void 0,
2479
+ extra: context.extra,
2480
+ error
2481
+ };
2482
+ if (isDuplicate(`${report.source}|${report.name}|${report.message}|${report.route ?? ""}`)) {
2483
+ return report;
2484
+ }
2485
+ console.error(`[error:${report.source}] ${report.id}`, error);
2486
+ for (const reporter of reporters) {
2487
+ try {
2488
+ reporter(report);
2489
+ } catch (err) {
2490
+ console.warn("[error] reporter failed", err);
2491
+ }
2492
+ }
2493
+ try {
2494
+ const { error: _raw, ...payload } = report;
2495
+ emitDomainEvent(APP_ERROR_EVENT, payload, {
2496
+ actorId: report.userId,
2497
+ tenantId: report.tenantId
2498
+ });
2499
+ } catch (err) {
2500
+ console.warn("[error] event emit failed", err);
2501
+ }
2502
+ return report;
2503
+ }
2504
+ var uninstall = null;
2505
+ function installGlobalErrorHandlers() {
2506
+ if (uninstall) return uninstall;
2507
+ if (typeof window === "undefined") return () => {
2508
+ };
2509
+ const onError = (event) => {
2510
+ reportAppError(event.error ?? event.message, {
2511
+ source: "window",
2512
+ extra: { filename: event.filename, lineno: event.lineno, colno: event.colno }
2513
+ });
2514
+ };
2515
+ const onRejection = (event) => {
2516
+ reportAppError(event.reason, { source: "promise" });
2517
+ };
2518
+ window.addEventListener("error", onError);
2519
+ window.addEventListener("unhandledrejection", onRejection);
2520
+ uninstall = () => {
2521
+ window.removeEventListener("error", onError);
2522
+ window.removeEventListener("unhandledrejection", onRejection);
2523
+ uninstall = null;
2524
+ };
2525
+ return uninstall;
2526
+ }
2527
+ function createVendorReporter(client2) {
2528
+ return (report) => {
2529
+ const hint = {
2530
+ tags: {
2531
+ errorId: report.id,
2532
+ source: report.source,
2533
+ route: report.route ?? "unknown",
2534
+ tenantId: report.tenantId ?? "unknown"
2535
+ },
2536
+ extra: {
2537
+ errorId: report.id,
2538
+ location: report.location,
2539
+ componentStack: report.componentStack,
2540
+ userId: report.userId,
2541
+ occurredAt: report.occurredAt,
2542
+ ...report.extra
2543
+ }
2544
+ };
2545
+ if (!(report.error instanceof Error) && client2.captureMessage) {
2546
+ client2.captureMessage(`${report.name}: ${report.message}`, hint);
2547
+ return;
2548
+ }
2549
+ client2.captureException(report.error, hint);
2550
+ };
2551
+ }
2552
+
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 };
2067
2554
  //# sourceMappingURL=index.js.map
2068
2555
  //# sourceMappingURL=index.js.map