@createcms/core 0.1.1

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 (83) hide show
  1. package/README.md +169 -0
  2. package/dist/ab-edge/index.cjs +214 -0
  3. package/dist/ab-edge/index.d.cts +121 -0
  4. package/dist/ab-edge/index.d.ts +121 -0
  5. package/dist/ab-edge/index.js +205 -0
  6. package/dist/bin/createcms.js +3082 -0
  7. package/dist/db.cjs +496 -0
  8. package/dist/db.d.cts +128 -0
  9. package/dist/db.d.ts +128 -0
  10. package/dist/db.js +488 -0
  11. package/dist/index.cjs +13789 -0
  12. package/dist/index.d.cts +10277 -0
  13. package/dist/index.d.ts +10277 -0
  14. package/dist/index.js +13737 -0
  15. package/dist/nanoid.cjs +50 -0
  16. package/dist/nanoid.d.cts +29 -0
  17. package/dist/nanoid.d.ts +29 -0
  18. package/dist/nanoid.js +47 -0
  19. package/dist/next/index.cjs +60 -0
  20. package/dist/next/index.d.cts +141 -0
  21. package/dist/next/index.d.ts +141 -0
  22. package/dist/next/index.js +58 -0
  23. package/dist/next/middleware.cjs +113 -0
  24. package/dist/next/middleware.d.cts +77 -0
  25. package/dist/next/middleware.d.ts +77 -0
  26. package/dist/next/middleware.js +111 -0
  27. package/dist/plugins/ab-test/analytics/upstash.cjs +345 -0
  28. package/dist/plugins/ab-test/analytics/upstash.d.cts +193 -0
  29. package/dist/plugins/ab-test/analytics/upstash.d.ts +193 -0
  30. package/dist/plugins/ab-test/analytics/upstash.js +343 -0
  31. package/dist/plugins/ab-test/client.cjs +686 -0
  32. package/dist/plugins/ab-test/client.d.cts +233 -0
  33. package/dist/plugins/ab-test/client.d.ts +233 -0
  34. package/dist/plugins/ab-test/client.js +684 -0
  35. package/dist/plugins/ab-test/index.cjs +3400 -0
  36. package/dist/plugins/ab-test/index.d.cts +1131 -0
  37. package/dist/plugins/ab-test/index.d.ts +1131 -0
  38. package/dist/plugins/ab-test/index.js +3367 -0
  39. package/dist/plugins/client.cjs +20 -0
  40. package/dist/plugins/client.d.cts +3 -0
  41. package/dist/plugins/client.d.ts +3 -0
  42. package/dist/plugins/client.js +3 -0
  43. package/dist/plugins/consent/client.cjs +315 -0
  44. package/dist/plugins/consent/client.d.cts +145 -0
  45. package/dist/plugins/consent/client.d.ts +145 -0
  46. package/dist/plugins/consent/client.js +313 -0
  47. package/dist/plugins/consent/index.cjs +267 -0
  48. package/dist/plugins/consent/index.d.cts +618 -0
  49. package/dist/plugins/consent/index.d.ts +618 -0
  50. package/dist/plugins/consent/index.js +258 -0
  51. package/dist/plugins/i18n/index.cjs +2177 -0
  52. package/dist/plugins/i18n/index.d.cts +562 -0
  53. package/dist/plugins/i18n/index.d.ts +562 -0
  54. package/dist/plugins/i18n/index.js +2150 -0
  55. package/dist/plugins/media-optimize/index.cjs +315 -0
  56. package/dist/plugins/media-optimize/index.d.cts +144 -0
  57. package/dist/plugins/media-optimize/index.d.ts +144 -0
  58. package/dist/plugins/media-optimize/index.js +311 -0
  59. package/dist/plugins/multi-tenant/index.cjs +210 -0
  60. package/dist/plugins/multi-tenant/index.d.cts +431 -0
  61. package/dist/plugins/multi-tenant/index.d.ts +431 -0
  62. package/dist/plugins/multi-tenant/index.js +207 -0
  63. package/dist/plugins/server.cjs +24 -0
  64. package/dist/plugins/server.d.cts +3 -0
  65. package/dist/plugins/server.d.ts +3 -0
  66. package/dist/plugins/server.js +3 -0
  67. package/dist/react/blocks.cjs +233 -0
  68. package/dist/react/blocks.d.cts +320 -0
  69. package/dist/react/blocks.d.ts +320 -0
  70. package/dist/react/blocks.js +226 -0
  71. package/dist/react/index.cjs +901 -0
  72. package/dist/react/index.d.cts +992 -0
  73. package/dist/react/index.d.ts +992 -0
  74. package/dist/react/index.js +872 -0
  75. package/dist/react/tracking.cjs +243 -0
  76. package/dist/react/tracking.d.cts +364 -0
  77. package/dist/react/tracking.d.ts +364 -0
  78. package/dist/react/tracking.js +216 -0
  79. package/dist/react/variant.cjs +59 -0
  80. package/dist/react/variant.d.cts +26 -0
  81. package/dist/react/variant.d.ts +26 -0
  82. package/dist/react/variant.js +57 -0
  83. package/package.json +303 -0
@@ -0,0 +1,258 @@
1
+ // ============================================================================
2
+ // Constants
3
+ // ============================================================================
4
+ /** Default-deny: nothing is granted until a CMP / Consent Mode signal says so. */ const DENIED_ALL = {
5
+ analytics_storage: 'denied',
6
+ ad_storage: 'denied',
7
+ ad_user_data: 'denied',
8
+ ad_personalization: 'denied'
9
+ };
10
+ /**
11
+ * How long (ms) to buffer events before resolving the gate when no consent
12
+ * DECISION has arrived yet — the Consent Mode `wait_for_update` window. Render
13
+ * is NEVER blocked on this; only event emission waits.
14
+ */ const CONSENT_WAIT_MS = 2000;
15
+ // ============================================================================
16
+ // Pure: parse Consent Mode v2 entries off a dataLayer
17
+ // ============================================================================
18
+ const SIGNALS = [
19
+ 'analytics_storage',
20
+ 'ad_storage',
21
+ 'ad_user_data',
22
+ 'ad_personalization'
23
+ ];
24
+ function isSignal(value) {
25
+ return value === 'granted' || value === 'denied';
26
+ }
27
+ /**
28
+ * Extracts the mode + partial {@link ConsentState} from a single dataLayer entry
29
+ * IF it is a Consent Mode command (`gtag('consent','default'|'update',{...})`,
30
+ * which lands on the dataLayer as an arguments-like `['consent', mode, params]`).
31
+ * Returns `null` for any non-consent entry. The `mode` matters: a `default` only
32
+ * seeds state, while an `update` is the user's decision (see {@link ConsentGate}).
33
+ */ function parseConsentEntry(entry) {
34
+ if (entry == null || typeof entry !== 'object') return null;
35
+ // Works for both real arrays and the arguments-objects gtag pushes.
36
+ const indexed = entry;
37
+ if (indexed[0] !== 'consent') return null;
38
+ const mode = indexed[1];
39
+ if (mode !== 'default' && mode !== 'update') return null;
40
+ const params = indexed[2];
41
+ if (params == null || typeof params !== 'object') return null;
42
+ const out = {};
43
+ for (const signal of SIGNALS){
44
+ const v = params[signal];
45
+ if (isSignal(v)) out[signal] = v;
46
+ }
47
+ return Object.keys(out).length > 0 ? {
48
+ mode,
49
+ state: out
50
+ } : null;
51
+ }
52
+ /** Parses every Consent Mode command on a dataLayer, in order. */ function parseConsentEntries(dataLayer) {
53
+ const out = [];
54
+ for (const entry of dataLayer){
55
+ const parsed = parseConsentEntry(entry);
56
+ if (parsed) out.push(parsed);
57
+ }
58
+ return out;
59
+ }
60
+ function createConsentGate(initial = DENIED_ALL) {
61
+ let state = {
62
+ ...initial
63
+ };
64
+ let resolved = false;
65
+ let buffer = [];
66
+ const listeners = new Set();
67
+ const notify = ()=>{
68
+ for (const l of listeners)l({
69
+ ...state
70
+ }, resolved);
71
+ };
72
+ const drain = ()=>{
73
+ if (!resolved) return;
74
+ const pending = buffer;
75
+ buffer = [];
76
+ const granted = state.analytics_storage === 'granted';
77
+ for (const item of pending){
78
+ if (granted) item.effect();
79
+ else item.onDrop?.();
80
+ }
81
+ };
82
+ return {
83
+ getState () {
84
+ return {
85
+ ...state
86
+ };
87
+ },
88
+ isGranted (purpose) {
89
+ return state[purpose] === 'granted';
90
+ },
91
+ isResolved () {
92
+ return resolved;
93
+ },
94
+ applyDefault (update) {
95
+ state = {
96
+ ...state,
97
+ ...update
98
+ };
99
+ notify();
100
+ },
101
+ applyUpdate (update) {
102
+ state = {
103
+ ...state,
104
+ ...update
105
+ };
106
+ // Only a decision about analytics (or one arriving after we've already
107
+ // resolved) drains. A partial update touching only ad_* keeps buffering.
108
+ if ('analytics_storage' in update || resolved) {
109
+ resolved = true;
110
+ notify();
111
+ drain();
112
+ } else {
113
+ notify();
114
+ }
115
+ },
116
+ resolve () {
117
+ if (resolved) return;
118
+ resolved = true;
119
+ notify();
120
+ drain();
121
+ },
122
+ run (effect, onDrop) {
123
+ if (!resolved) {
124
+ buffer.push({
125
+ effect,
126
+ onDrop
127
+ });
128
+ return;
129
+ }
130
+ if (state.analytics_storage === 'granted') effect();
131
+ else onDrop?.();
132
+ },
133
+ onChange (listener) {
134
+ listeners.add(listener);
135
+ return ()=>listeners.delete(listener);
136
+ },
137
+ reset () {
138
+ const pending = buffer;
139
+ buffer = [];
140
+ state = {
141
+ ...DENIED_ALL
142
+ };
143
+ resolved = true;
144
+ for (const item of pending)item.onDrop?.();
145
+ notify();
146
+ }
147
+ };
148
+ }
149
+ // ============================================================================
150
+ // Pure: visitor-key resolution (consent-gated persistence)
151
+ // ============================================================================
152
+ /**
153
+ * Decides which visitor key to use and whether it may be persisted. Before
154
+ * `analytics_storage` is granted, the key is in-memory only (page lifetime, no
155
+ * device storage). On grant, an existing cookie wins; otherwise the in-memory
156
+ * key is promoted to the cookie so a buffered impression and later events share
157
+ * one identity.
158
+ */ function resolveVisitorKey(opts) {
159
+ if (opts.granted) {
160
+ if (opts.cookieKey) {
161
+ return {
162
+ key: opts.cookieKey,
163
+ persist: false,
164
+ memKey: opts.cookieKey
165
+ };
166
+ }
167
+ const key = opts.memKey ?? opts.generate();
168
+ return {
169
+ key,
170
+ persist: true,
171
+ memKey: key
172
+ };
173
+ }
174
+ const key = opts.memKey ?? opts.generate();
175
+ return {
176
+ key,
177
+ persist: false,
178
+ memKey: key
179
+ };
180
+ }
181
+
182
+ function routeConsentEntry(gate, entry) {
183
+ const parsed = parseConsentEntry(entry);
184
+ if (!parsed) return;
185
+ // A `default` only seeds state; an `update` (or explicit setConsent) is the
186
+ // decision that may resolve the gate.
187
+ if (parsed.mode === 'default') gate.applyDefault(parsed.state);
188
+ else gate.applyUpdate(parsed.state);
189
+ }
190
+ /**
191
+ * Zero-config consent: reads Consent Mode v2 commands off `window.dataLayer`
192
+ * (already-present `default`/`update` entries and future pushes) and feeds the
193
+ * gate. Resilient to GTM/gtag.js loading LATER — which reassigns `dataLayer` /
194
+ * its `push` and would discard an in-place patch — via a short re-scan poll over
195
+ * the wait window that re-reads `window.dataLayer` fresh each tick (and re-scans
196
+ * from 0 if the array was replaced). The `push` patch is only a fast path. When
197
+ * running GTM, driving consent explicitly via `setConsent` from the CMP's
198
+ * Consent Mode update callback is the most reliable path.
199
+ */ function startConsentAutoRead(gate) {
200
+ if (typeof window === 'undefined') return;
201
+ const w = window;
202
+ let scannedArray = null;
203
+ let idx = 0;
204
+ const scan = ()=>{
205
+ const dl = w.dataLayer = w.dataLayer || [];
206
+ if (dl !== scannedArray) {
207
+ // First scan, or the host (GTM) replaced the array — re-read from 0.
208
+ scannedArray = dl;
209
+ idx = 0;
210
+ }
211
+ for(; idx < dl.length; idx++)routeConsentEntry(gate, dl[idx]);
212
+ // Best-effort fast path: observe pushes on the current array (once).
213
+ if (!dl.__cmsConsentObserved) {
214
+ dl.__cmsConsentObserved = true;
215
+ const originalPush = dl.push.bind(dl);
216
+ dl.push = (...args)=>{
217
+ const ret = originalPush(...args);
218
+ try {
219
+ for (const arg of args)routeConsentEntry(gate, arg);
220
+ } catch {
221
+ // never let consent observation break a host dataLayer push
222
+ }
223
+ return ret;
224
+ };
225
+ }
226
+ };
227
+ scan();
228
+ // Poll fallback: survives GTM clobbering the push hook / replacing the array.
229
+ const interval = setInterval(()=>{
230
+ if (gate.isResolved()) {
231
+ clearInterval(interval);
232
+ return;
233
+ }
234
+ try {
235
+ scan();
236
+ } catch {
237
+ // ignore
238
+ }
239
+ }, 300);
240
+ }
241
+
242
+ const PLUGIN_ID = 'consent';
243
+ /**
244
+ * The consent plugin. Owns the generic Google Consent Mode v2 infrastructure
245
+ * (the buffer-then-flush gate, the dataLayer/CMP auto-read, the state model)
246
+ * that any consumer can ride — A/B tracking, analytics sinks, or consent-gated
247
+ * rendering of embedded third-party content.
248
+ *
249
+ * Server-side it is a marker plugin (no schema/endpoints/hooks): consent is a
250
+ * client-side concern today. The client capability (gate + setConsent/getConsent
251
+ * + the <ConsentGate> render wrapper) is exposed via the client entry.
252
+ */ function consent() {
253
+ return {
254
+ id: PLUGIN_ID
255
+ };
256
+ }
257
+
258
+ export { CONSENT_WAIT_MS, DENIED_ALL, consent, createConsentGate, parseConsentEntries, parseConsentEntry, resolveVisitorKey, startConsentAutoRead };