@schematichq/schematic-js 0.1.11 → 0.1.12
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.
- package/dist/schematic.browser.js +1 -1
- package/dist/schematic.cjs.js +32 -31
- package/dist/schematic.d.ts +1 -1
- package/dist/schematic.esm.js +32 -31
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";(()=>{var
|
|
1
|
+
"use strict";(()=>{var l,k=new Uint8Array(16);function p(){if(!l&&(l=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!l))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return l(k)}var i=[];for(let r=0;r<256;++r)i.push((r+256).toString(16).slice(1));function m(r,e=0){return i[r[e+0]]+i[r[e+1]]+i[r[e+2]]+i[r[e+3]]+"-"+i[r[e+4]]+i[r[e+5]]+"-"+i[r[e+6]]+i[r[e+7]]+"-"+i[r[e+8]]+i[r[e+9]]+"-"+i[r[e+10]]+i[r[e+11]]+i[r[e+12]]+i[r[e+13]]+i[r[e+14]]+i[r[e+15]]}var x=typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto),y={randomUUID:x};function b(r,e,t){if(y.randomUUID&&!e&&!r)return y.randomUUID();r=r||{};let n=r.random||(r.rng||p)();if(n[6]=n[6]&15|64,n[8]=n[8]&63|128,e){t=t||0;for(let s=0;s<16;++s)e[t+s]=n[s];return e}return m(n)}var u=b;var g="schematicId";var h=class{apiKey;apiUrl="https://api.schematichq.com";webSocketUrl="wss://api.schematichq.com";eventUrl="https://c.schematichq.com";conn=null;context={};eventQueue;storage;useWebSocket=!1;values={};flagListener;constructor(e,t){this.apiKey=e,this.eventQueue=[],this.useWebSocket=t?.useWebSocket??!1,this.flagListener=t?.flagListener,t?.storage?this.storage=t.storage:typeof localStorage<"u"&&(this.storage=localStorage),t?.apiUrl!==void 0&&(this.apiUrl=t.apiUrl),t?.eventUrl!==void 0&&(this.eventUrl=t.eventUrl),t?.webSocketUrl!==void 0&&(this.webSocketUrl=t.webSocketUrl),window?.addEventListener&&window.addEventListener("beforeunload",()=>{this.flushEventQueue()})}async checkFlag(e){let{fallback:t=!1,key:n}=e,s=e.context||this.context;if(this.useWebSocket){let o=this.values[c(s)]??{};return typeof o[n]>"u"?t:o[n]}let a=`${this.apiUrl}/flags/${n}/check`;return fetch(a,{method:"POST",headers:{"X-Schematic-Api-Key":this.apiKey,"Content-Type":"application/json;charset=UTF-8"},body:JSON.stringify(s)}).then(o=>{if(!o.ok)throw new Error("Network response was not ok");return o.json()}).then(o=>o.data.value).catch(o=>(console.error("There was a problem with the fetch operation:",o),t))}checkFlags=async e=>{e=e||this.context;let t=`${this.apiUrl}/flags/check`,n=JSON.stringify(e);return fetch(t,{method:"POST",headers:{"Content-Type":"application/json;charset=UTF-8","X-Schematic-Api-Key":this.apiKey},body:n}).then(s=>{if(!s.ok)throw new Error("Network response was not ok");return s.json()}).then(s=>(s?.data?.flags??[]).reduce((a,o)=>(a[o.flag]=o.value,a),{})).catch(s=>(console.error("There was a problem with the fetch operation:",s),!1))};cleanup=async()=>{if(this.conn)try{(await this.conn).close()}catch(e){console.error("Error during cleanup:",e)}finally{this.conn=null}};identify=e=>(this.setContext({company:e.company?.keys,user:e.keys}),this.handleEvent("identify",e));setContext=async e=>this.useWebSocket?(this.conn||(this.conn=this.wsConnect()),this.conn.then(t=>this.wsSendMessage(t,e))):(this.context=e,Promise.resolve());track=e=>{let{company:t,user:n,event:s,traits:a}=e;return this.handleEvent("track",{company:t??this.context.company,event:s,traits:a??{},user:n??this.context.user})};flushEventQueue=()=>{for(;this.eventQueue.length>0;){let e=this.eventQueue.shift();e&&this.sendEvent(e)}};getAnonymousId=()=>{if(!this.storage)return u();let e=this.storage.getItem(g);if(typeof e<"u")return e;let t=u();return this.storage.setItem(g,t),t};handleEvent=(e,t)=>{let n={api_key:this.apiKey,body:t,sent_at:new Date().toISOString(),tracker_event_id:u(),tracker_user_id:this.getAnonymousId(),type:e};return document?.hidden?this.storeEvent(n):this.sendEvent(n)};sendEvent=async e=>{let t=`${this.eventUrl}/e`,n=JSON.stringify(e);try{await fetch(t,{method:"POST",headers:{"Content-Type":"application/json;charset=UTF-8"},body:n})}catch(s){console.error("Error sending Schematic event: ",s)}return Promise.resolve()};storeEvent=e=>(this.eventQueue.push(e),Promise.resolve());wsConnect=()=>new Promise((e,t)=>{let n=`${this.webSocketUrl}/flags/bootstrap`,s=new WebSocket(n);s.onopen=()=>{e(s)},s.onerror=a=>{t(a)},s.onclose=()=>{this.conn=null}});wsSendMessage=(e,t)=>new Promise((n,s)=>{if(c(t)==c(this.context)){n();return}this.context=t;let a=()=>{let o=!1,d=f=>{let S=JSON.parse(f.data);c(t)in this.values||(this.values[c(t)]={}),(S.flags??[]).forEach(v=>{this.values[c(t)][v.flag]=v.value}),this.flagListener&&this.flagListener(this.values[c(t)]),o||(o=!0,n()),e.removeEventListener("message",d)};e.addEventListener("message",d),e.send(JSON.stringify({apiKey:this.apiKey,data:t}))};e.readyState===WebSocket.OPEN?a():e.readyState===WebSocket.CONNECTING?e.addEventListener("open",a):s("WebSocket is not open or connecting")})};function c(r){let e=Object.keys(r).reduce((t,n)=>{let a=Object.keys(r[n]||{}).sort().reduce((o,d)=>(o[d]=r[n][d],o),{});return t[n]=a,t},{});return JSON.stringify(e)}window.Schematic=h;})();
|
|
2
2
|
/* @preserve */
|
package/dist/schematic.cjs.js
CHANGED
|
@@ -168,9 +168,16 @@ var Schematic = class {
|
|
|
168
168
|
return false;
|
|
169
169
|
});
|
|
170
170
|
};
|
|
171
|
-
cleanup = () => {
|
|
171
|
+
cleanup = async () => {
|
|
172
172
|
if (this.conn) {
|
|
173
|
-
|
|
173
|
+
try {
|
|
174
|
+
const socket = await this.conn;
|
|
175
|
+
socket.close();
|
|
176
|
+
} catch (error) {
|
|
177
|
+
console.error("Error during cleanup:", error);
|
|
178
|
+
} finally {
|
|
179
|
+
this.conn = null;
|
|
180
|
+
}
|
|
174
181
|
}
|
|
175
182
|
};
|
|
176
183
|
// Send an identify event
|
|
@@ -185,16 +192,16 @@ var Schematic = class {
|
|
|
185
192
|
// this will open a websocket connection (if not already open)
|
|
186
193
|
// and submit this context. The promise will resolve when the
|
|
187
194
|
// websocket sends back an initial set of flag values.
|
|
188
|
-
setContext = (context) => {
|
|
195
|
+
setContext = async (context) => {
|
|
189
196
|
if (!this.useWebSocket) {
|
|
190
197
|
this.context = context;
|
|
191
198
|
return Promise.resolve();
|
|
192
199
|
}
|
|
193
|
-
|
|
194
|
-
this.wsConnect()
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
200
|
+
if (!this.conn) {
|
|
201
|
+
this.conn = this.wsConnect();
|
|
202
|
+
}
|
|
203
|
+
return this.conn.then((socket) => {
|
|
204
|
+
return this.wsSendMessage(socket, context);
|
|
198
205
|
});
|
|
199
206
|
};
|
|
200
207
|
// Send track event
|
|
@@ -263,36 +270,30 @@ var Schematic = class {
|
|
|
263
270
|
return Promise.resolve();
|
|
264
271
|
};
|
|
265
272
|
wsConnect = () => {
|
|
266
|
-
return new Promise((resolve) => {
|
|
267
|
-
if (this.conn) {
|
|
268
|
-
resolve();
|
|
269
|
-
}
|
|
273
|
+
return new Promise((resolve, reject) => {
|
|
270
274
|
const wsUrl = `${this.webSocketUrl}/flags/bootstrap`;
|
|
271
275
|
const webSocket = new WebSocket(wsUrl);
|
|
272
|
-
this.conn = webSocket;
|
|
273
276
|
webSocket.onopen = () => {
|
|
274
|
-
resolve();
|
|
277
|
+
resolve(webSocket);
|
|
278
|
+
};
|
|
279
|
+
webSocket.onerror = (error) => {
|
|
280
|
+
reject(error);
|
|
275
281
|
};
|
|
276
282
|
webSocket.onclose = () => {
|
|
277
283
|
this.conn = null;
|
|
278
284
|
};
|
|
279
285
|
});
|
|
280
286
|
};
|
|
281
|
-
|
|
282
|
-
wsSendMessage = (context) => {
|
|
287
|
+
wsSendMessage = (socket, context) => {
|
|
283
288
|
return new Promise((resolve, reject) => {
|
|
284
289
|
if (contextString(context) == contextString(this.context)) {
|
|
285
290
|
resolve();
|
|
286
291
|
return;
|
|
287
292
|
}
|
|
288
293
|
this.context = context;
|
|
289
|
-
|
|
290
|
-
reject("Not connected");
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
if (this.conn.readyState === WebSocket.OPEN) {
|
|
294
|
+
const sendMessage = () => {
|
|
294
295
|
let resolved = false;
|
|
295
|
-
|
|
296
|
+
const messageHandler = (event) => {
|
|
296
297
|
const message = JSON.parse(event.data);
|
|
297
298
|
if (!(contextString(context) in this.values)) {
|
|
298
299
|
this.values[contextString(context)] = {};
|
|
@@ -309,22 +310,22 @@ var Schematic = class {
|
|
|
309
310
|
resolved = true;
|
|
310
311
|
resolve();
|
|
311
312
|
}
|
|
313
|
+
socket.removeEventListener("message", messageHandler);
|
|
312
314
|
};
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
};
|
|
316
|
-
this.conn.send(
|
|
315
|
+
socket.addEventListener("message", messageHandler);
|
|
316
|
+
socket.send(
|
|
317
317
|
JSON.stringify({
|
|
318
318
|
apiKey: this.apiKey,
|
|
319
319
|
data: context
|
|
320
320
|
})
|
|
321
321
|
);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
322
|
+
};
|
|
323
|
+
if (socket.readyState === WebSocket.OPEN) {
|
|
324
|
+
sendMessage();
|
|
325
|
+
} else if (socket.readyState === WebSocket.CONNECTING) {
|
|
326
|
+
socket.addEventListener("open", sendMessage);
|
|
326
327
|
} else {
|
|
327
|
-
reject("
|
|
328
|
+
reject("WebSocket is not open or connecting");
|
|
328
329
|
}
|
|
329
330
|
});
|
|
330
331
|
};
|
package/dist/schematic.d.ts
CHANGED
|
@@ -64,7 +64,7 @@ export declare class Schematic {
|
|
|
64
64
|
constructor(apiKey: string, options?: SchematicOptions);
|
|
65
65
|
checkFlag(options: CheckOptions): Promise<boolean>;
|
|
66
66
|
checkFlags: (context?: SchematicContext) => Promise<Record<string, boolean>>;
|
|
67
|
-
cleanup: () => void
|
|
67
|
+
cleanup: () => Promise<void>;
|
|
68
68
|
identify: (body: EventBodyIdentify) => Promise<void>;
|
|
69
69
|
setContext: (context: SchematicContext) => Promise<void>;
|
|
70
70
|
track: (body: EventBodyTrack) => Promise<void>;
|
package/dist/schematic.esm.js
CHANGED
|
@@ -142,9 +142,16 @@ var Schematic = class {
|
|
|
142
142
|
return false;
|
|
143
143
|
});
|
|
144
144
|
};
|
|
145
|
-
cleanup = () => {
|
|
145
|
+
cleanup = async () => {
|
|
146
146
|
if (this.conn) {
|
|
147
|
-
|
|
147
|
+
try {
|
|
148
|
+
const socket = await this.conn;
|
|
149
|
+
socket.close();
|
|
150
|
+
} catch (error) {
|
|
151
|
+
console.error("Error during cleanup:", error);
|
|
152
|
+
} finally {
|
|
153
|
+
this.conn = null;
|
|
154
|
+
}
|
|
148
155
|
}
|
|
149
156
|
};
|
|
150
157
|
// Send an identify event
|
|
@@ -159,16 +166,16 @@ var Schematic = class {
|
|
|
159
166
|
// this will open a websocket connection (if not already open)
|
|
160
167
|
// and submit this context. The promise will resolve when the
|
|
161
168
|
// websocket sends back an initial set of flag values.
|
|
162
|
-
setContext = (context) => {
|
|
169
|
+
setContext = async (context) => {
|
|
163
170
|
if (!this.useWebSocket) {
|
|
164
171
|
this.context = context;
|
|
165
172
|
return Promise.resolve();
|
|
166
173
|
}
|
|
167
|
-
|
|
168
|
-
this.wsConnect()
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
174
|
+
if (!this.conn) {
|
|
175
|
+
this.conn = this.wsConnect();
|
|
176
|
+
}
|
|
177
|
+
return this.conn.then((socket) => {
|
|
178
|
+
return this.wsSendMessage(socket, context);
|
|
172
179
|
});
|
|
173
180
|
};
|
|
174
181
|
// Send track event
|
|
@@ -237,36 +244,30 @@ var Schematic = class {
|
|
|
237
244
|
return Promise.resolve();
|
|
238
245
|
};
|
|
239
246
|
wsConnect = () => {
|
|
240
|
-
return new Promise((resolve) => {
|
|
241
|
-
if (this.conn) {
|
|
242
|
-
resolve();
|
|
243
|
-
}
|
|
247
|
+
return new Promise((resolve, reject) => {
|
|
244
248
|
const wsUrl = `${this.webSocketUrl}/flags/bootstrap`;
|
|
245
249
|
const webSocket = new WebSocket(wsUrl);
|
|
246
|
-
this.conn = webSocket;
|
|
247
250
|
webSocket.onopen = () => {
|
|
248
|
-
resolve();
|
|
251
|
+
resolve(webSocket);
|
|
252
|
+
};
|
|
253
|
+
webSocket.onerror = (error) => {
|
|
254
|
+
reject(error);
|
|
249
255
|
};
|
|
250
256
|
webSocket.onclose = () => {
|
|
251
257
|
this.conn = null;
|
|
252
258
|
};
|
|
253
259
|
});
|
|
254
260
|
};
|
|
255
|
-
|
|
256
|
-
wsSendMessage = (context) => {
|
|
261
|
+
wsSendMessage = (socket, context) => {
|
|
257
262
|
return new Promise((resolve, reject) => {
|
|
258
263
|
if (contextString(context) == contextString(this.context)) {
|
|
259
264
|
resolve();
|
|
260
265
|
return;
|
|
261
266
|
}
|
|
262
267
|
this.context = context;
|
|
263
|
-
|
|
264
|
-
reject("Not connected");
|
|
265
|
-
return;
|
|
266
|
-
}
|
|
267
|
-
if (this.conn.readyState === WebSocket.OPEN) {
|
|
268
|
+
const sendMessage = () => {
|
|
268
269
|
let resolved = false;
|
|
269
|
-
|
|
270
|
+
const messageHandler = (event) => {
|
|
270
271
|
const message = JSON.parse(event.data);
|
|
271
272
|
if (!(contextString(context) in this.values)) {
|
|
272
273
|
this.values[contextString(context)] = {};
|
|
@@ -283,22 +284,22 @@ var Schematic = class {
|
|
|
283
284
|
resolved = true;
|
|
284
285
|
resolve();
|
|
285
286
|
}
|
|
287
|
+
socket.removeEventListener("message", messageHandler);
|
|
286
288
|
};
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
};
|
|
290
|
-
this.conn.send(
|
|
289
|
+
socket.addEventListener("message", messageHandler);
|
|
290
|
+
socket.send(
|
|
291
291
|
JSON.stringify({
|
|
292
292
|
apiKey: this.apiKey,
|
|
293
293
|
data: context
|
|
294
294
|
})
|
|
295
295
|
);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
296
|
+
};
|
|
297
|
+
if (socket.readyState === WebSocket.OPEN) {
|
|
298
|
+
sendMessage();
|
|
299
|
+
} else if (socket.readyState === WebSocket.CONNECTING) {
|
|
300
|
+
socket.addEventListener("open", sendMessage);
|
|
300
301
|
} else {
|
|
301
|
-
reject("
|
|
302
|
+
reject("WebSocket is not open or connecting");
|
|
302
303
|
}
|
|
303
304
|
});
|
|
304
305
|
};
|
package/package.json
CHANGED