bruce-models 2.0.9 → 2.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.
@@ -3146,260 +3146,125 @@ module.exports = localforage_js;
3146
3146
  });
3147
3147
  });
3148
3148
 
3149
- var ObjectUtils;
3150
- (function (ObjectUtils) {
3151
- /**
3152
- * Generates a Bruce compatible UID.
3153
- * @returns
3154
- */
3155
- function UId() {
3156
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
3157
- const r = Math.random() * 16 | 0, v = c == "x" ? r : (r & 0x3 | 0x8);
3158
- return v.toString(16);
3159
- });
3160
- }
3161
- ObjectUtils.UId = UId;
3162
- })(ObjectUtils || (ObjectUtils = {}));
3163
-
3164
- class CacheDictionary {
3149
+ const CACHE_VERSION_PREFIX = "v2_";
3150
+ class CacheUtil {
3165
3151
  constructor(id) {
3166
- this.memory = Object.create(null);
3167
- if (!id) {
3168
- id = "BRUCE_UI_MODELS_CACHE_DICT_" + ObjectUtils.UId();
3169
- }
3170
- this.id = id;
3171
3152
  this.store = localforage.createInstance({
3172
- name: id
3173
- });
3174
- }
3175
- get Id() {
3176
- return this.id;
3177
- }
3178
- GetItems() {
3179
- return __awaiter(this, void 0, void 0, function* () {
3180
- if (this.items == null) {
3181
- const raw = yield this.store.getItem(this.id);
3182
- if (raw == null) {
3183
- this.items = [];
3184
- }
3185
- else {
3186
- // Check if any are expired.
3187
- // We can clean this every first time we load.
3188
- const now = new Date().getTime();
3189
- for (const item of raw) {
3190
- if (item.duration > -1 && (now - item.created) / 1000 > item.duration) {
3191
- if (item.inMemory) {
3192
- this.memory[item.key] = null;
3193
- delete this.memory[item.key];
3194
- }
3195
- else {
3196
- yield this.store.removeItem(item.key);
3197
- }
3198
- }
3199
- }
3200
- this.items = raw;
3201
- }
3202
- }
3203
- return this.items;
3204
- });
3205
- }
3206
- GetKeys() {
3207
- return __awaiter(this, void 0, void 0, function* () {
3208
- return (yield this.GetItems()).map(x => "" + x.key);
3153
+ name: CACHE_VERSION_PREFIX + id,
3209
3154
  });
3155
+ this.inMemoryPromises = {};
3156
+ this.keyVersions = {};
3210
3157
  }
3211
- Set(key, value, duration) {
3158
+ Set(key, value, duration = 300000) {
3212
3159
  return __awaiter(this, void 0, void 0, function* () {
3213
- key = "" + key;
3214
- const items = yield this.GetItems();
3215
- const itemIndex = items.findIndex(x => x.key == key);
3216
- if (itemIndex > -1) {
3217
- const item = items[itemIndex];
3218
- if (item.inMemory) {
3219
- this.memory[item.key] = null;
3220
- delete this.memory[item.key];
3221
- }
3222
- else {
3223
- yield this.store.removeItem(item.key);
3224
- }
3225
- items.splice(itemIndex, 1);
3226
- }
3227
- const item = {
3228
- key: key,
3229
- duration: duration,
3230
- created: new Date().getTime(),
3231
- inMemory: false
3232
- };
3233
- // Short duration, keep in memory.
3234
- if (duration < 60) {
3235
- item.inMemory = true;
3236
- this.memory[item.key] = value;
3237
- }
3238
- // Let's resolve and store the value in local-storage.
3239
- // If resolution crashes then we'll keep retaining that in memory.
3240
- else if (value instanceof Promise) {
3241
- value.then((x) => __awaiter(this, void 0, void 0, function* () {
3242
- try {
3243
- const items = yield this.GetItems();
3244
- const item = items.find(x => x.key == key);
3245
- if (!item) {
3246
- console.log("Item was removed from cache before promise resolved.", key, items);
3247
- return;
3248
- }
3249
- try {
3250
- yield this.store.setItem(item.key, x);
3251
- item.inMemory = false;
3252
- this.memory[item.key] = null;
3253
- delete this.memory[item.key];
3254
- yield this.store.setItem(this.id, items);
3255
- }
3256
- catch (e) {
3257
- console.warn(e);
3258
- }
3160
+ if (value instanceof Promise) {
3161
+ this.inMemoryPromises[key] = value;
3162
+ const currentVersion = (this.keyVersions[key] = (this.keyVersions[key] || 0) + 1);
3163
+ value
3164
+ .then((resolvedValue) => {
3165
+ if (this.keyVersions[key] === currentVersion) {
3166
+ this.Set(key, resolvedValue, duration);
3259
3167
  }
3260
- catch (e) {
3261
- console.warn(e);
3168
+ })
3169
+ .catch((error) => {
3170
+ if (this.keyVersions[key] === currentVersion) {
3171
+ this.Set(key, error, duration);
3262
3172
  }
3263
- }));
3264
- item.inMemory = true;
3265
- this.memory[item.key] = value;
3173
+ })
3174
+ .finally(() => {
3175
+ delete this.inMemoryPromises[key];
3176
+ });
3266
3177
  }
3267
- if (!item.inMemory) {
3268
- try {
3269
- yield this.store.setItem(item.key, value);
3270
- }
3271
- catch (e) {
3272
- item.inMemory = true;
3273
- this.memory[item.key] = value;
3274
- console.warn(e);
3275
- }
3178
+ else {
3179
+ const item = {
3180
+ value,
3181
+ expiry: Date.now() + duration,
3182
+ };
3183
+ yield this.store.setItem(key, item);
3276
3184
  }
3277
- items.push(item);
3278
- yield this.store.setItem(this.id, items);
3279
- this.items = items;
3280
3185
  });
3281
3186
  }
3282
- Remove(key) {
3187
+ Get(key) {
3283
3188
  return __awaiter(this, void 0, void 0, function* () {
3284
- key = "" + key;
3285
- const items = yield this.GetItems();
3286
- const index = items.findIndex(x => x.key == key);
3287
- if (index >= 0) {
3288
- const item = items[index];
3289
- if (item.inMemory) {
3290
- this.memory[item.key] = null;
3291
- delete this.memory[item.key];
3292
- }
3293
- else {
3294
- this.store.removeItem(item.key);
3295
- }
3296
- items.splice(index, 1);
3297
- this.store.setItem(this.id, items);
3189
+ if (this.inMemoryPromises[key]) {
3190
+ return this.inMemoryPromises[key];
3298
3191
  }
3299
- this.items = items;
3300
- });
3301
- }
3302
- Clear() {
3303
- return __awaiter(this, void 0, void 0, function* () {
3304
- const items = yield this.GetItems();
3305
- for (const item of items) {
3306
- if (item.inMemory) {
3307
- this.store.removeItem(item.key);
3308
- }
3192
+ const item = (yield this.store.getItem(key));
3193
+ if (!item) {
3194
+ return null;
3309
3195
  }
3310
- this.store.setItem(this.id, []);
3311
- this.items = [];
3312
- this.memory = Object.create(null);
3196
+ if (Date.now() > item.expiry) {
3197
+ yield this.store.removeItem(key);
3198
+ return null;
3199
+ }
3200
+ return item.value;
3313
3201
  });
3314
3202
  }
3315
- GetData(key) {
3203
+ ClearCache(pattern, mode = "equals") {
3316
3204
  return __awaiter(this, void 0, void 0, function* () {
3317
- key = "" + key;
3318
- const item = (yield this.GetItems()).find(x => x.key == key);
3319
- const isExpired = item == null || item.duration > -1 && (new Date().getTime() - item.created) / 1000 > item.duration;
3320
- if (isExpired) {
3321
- this.Remove(key);
3322
- return null;
3205
+ const keys = yield this.store.keys();
3206
+ const checkFuncs = {
3207
+ equals: (key) => key === pattern,
3208
+ contains: (key) => key.includes(pattern),
3209
+ startswith: (key) => key.startsWith(pattern),
3210
+ };
3211
+ const check = checkFuncs[mode];
3212
+ if (!check) {
3213
+ throw new Error("Invalid mode");
3323
3214
  }
3324
- if (item.inMemory) {
3325
- return this.memory[item.key];
3215
+ for (const key of keys) {
3216
+ if (check(key)) {
3217
+ yield this.store.removeItem(key);
3218
+ }
3326
3219
  }
3327
- const raw = yield this.store.getItem(item.key);
3328
- if (raw == null) {
3329
- return null;
3220
+ for (const key in this.inMemoryPromises) {
3221
+ if (check(key)) {
3222
+ delete this.inMemoryPromises[key];
3223
+ this.keyVersions[key]++;
3224
+ }
3330
3225
  }
3331
- return raw;
3332
3226
  });
3333
3227
  }
3334
3228
  }
3335
3229
  class CacheControl {
3336
3230
  constructor(id) {
3337
3231
  this.Disabled = false;
3338
- this.data = new CacheDictionary(id);
3232
+ this.data = new CacheUtil(id);
3339
3233
  }
3340
3234
  /**
3341
3235
  * @param id
3342
3236
  * @param data
3343
3237
  * @param duration seconds to keep the data in cache. -1 for infinite.
3344
3238
  */
3345
- Set(id, data, duration = -1) {
3239
+ Set(id, data, duration = 300) {
3346
3240
  return __awaiter(this, void 0, void 0, function* () {
3347
- return this.data.Set(id, data, duration);
3241
+ const durationMs = duration === -1 ? undefined : duration * 1000;
3242
+ return this.data.Set(String(id), data, durationMs);
3348
3243
  });
3349
3244
  }
3350
3245
  Get(id) {
3351
3246
  return __awaiter(this, void 0, void 0, function* () {
3352
- return this.data.GetData(id);
3247
+ return (yield this.data.Get(String(id)));
3353
3248
  });
3354
3249
  }
3355
3250
  Clear() {
3356
3251
  return __awaiter(this, void 0, void 0, function* () {
3357
- return this.data.Clear();
3252
+ return this.data.ClearCache("");
3358
3253
  });
3359
3254
  }
3360
3255
  Remove(id) {
3361
3256
  return __awaiter(this, void 0, void 0, function* () {
3362
- return this.data.Remove(id);
3257
+ return this.data.ClearCache(String(id), "equals");
3363
3258
  });
3364
3259
  }
3365
3260
  RemoveByStartsWith(text) {
3366
3261
  return __awaiter(this, void 0, void 0, function* () {
3367
- const items = [...(yield this.data.GetItems())];
3368
- for (const item of items) {
3369
- if (item.key.startsWith(text)) {
3370
- yield this.data.Remove(item.key);
3371
- }
3372
- }
3262
+ return this.data.ClearCache(text, "startswith");
3373
3263
  });
3374
3264
  }
3375
3265
  RemoveByContains(text) {
3376
3266
  return __awaiter(this, void 0, void 0, function* () {
3377
- const items = [...(yield this.data.GetItems())];
3378
- for (const item of items) {
3379
- if (item.key.includes(text)) {
3380
- yield this.data.Remove(item.key);
3381
- }
3382
- }
3383
- });
3384
- }
3385
- GetKeys() {
3386
- return __awaiter(this, void 0, void 0, function* () {
3387
- if (this.Disabled) {
3388
- return [];
3389
- }
3390
- const items = yield this.data.GetItems();
3391
- return items.map(x => x.key);
3392
- });
3393
- }
3394
- GetValues() {
3395
- return __awaiter(this, void 0, void 0, function* () {
3396
- if (this.Disabled) {
3397
- return [];
3398
- }
3399
- const items = yield this.data.GetItems();
3400
- const keys = items.map(x => x.key);
3401
- const values = yield Promise.all(keys.map(key => this.data.GetData(key)));
3402
- return values.filter(x => x != null);
3267
+ return this.data.ClearCache(text, "contains");
3403
3268
  });
3404
3269
  }
3405
3270
  }
@@ -4658,6 +4523,21 @@ var Color;
4658
4523
  Color.ColorFromStr = ColorFromStr;
4659
4524
  })(Color || (Color = {}));
4660
4525
 
4526
+ var ObjectUtils;
4527
+ (function (ObjectUtils) {
4528
+ /**
4529
+ * Generates a Bruce compatible UID.
4530
+ * @returns
4531
+ */
4532
+ function UId() {
4533
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
4534
+ const r = Math.random() * 16 | 0, v = c == "x" ? r : (r & 0x3 | 0x8);
4535
+ return v.toString(16);
4536
+ });
4537
+ }
4538
+ ObjectUtils.UId = UId;
4539
+ })(ObjectUtils || (ObjectUtils = {}));
4540
+
4661
4541
  /**
4662
4542
  * Utility to help with parsing and wrapping Bruce paths.
4663
4543
  */
@@ -4724,24 +4604,34 @@ var PathUtils;
4724
4604
  */
4725
4605
  var Entity;
4726
4606
  (function (Entity) {
4727
- function GetCacheKey(entityId, expandLocation) {
4728
- return `${Api.ECacheKey.Entity}${Api.ECacheKey.Id}${entityId}${String(Boolean(expandLocation))}`;
4607
+ function GetCacheKey(entityId, entityTypeId, expandLocation) {
4608
+ if (!entityTypeId) {
4609
+ entityTypeId = "";
4610
+ }
4611
+ return `${Api.ECacheKey.Entity}${Api.ECacheKey.Id}${entityId}${String(entityTypeId)}${String(Boolean(expandLocation))}`;
4729
4612
  }
4730
4613
  Entity.GetCacheKey = GetCacheKey;
4731
4614
  function Get(params) {
4732
4615
  return __awaiter(this, void 0, void 0, function* () {
4733
- const { api, entityId, req: reqParams, expandLocation } = params;
4616
+ const { api, entityId, req: reqParams, expandLocation, entityTypeId } = params;
4734
4617
  if (!entityId) {
4735
4618
  throw ("Entity ID is required.");
4736
4619
  }
4737
- const key = GetCacheKey(entityId, expandLocation);
4620
+ const key = GetCacheKey(entityId, entityTypeId, expandLocation);
4738
4621
  const cacheData = yield api.GetCacheItem(key, reqParams);
4739
4622
  if (cacheData) {
4740
4623
  return cacheData;
4741
4624
  }
4742
4625
  const prom = new Promise((res, rej) => __awaiter(this, void 0, void 0, function* () {
4743
4626
  try {
4744
- const data = yield api.GET(`entity/${entityId}${expandLocation ? "?$expand=location" : ""}`, Api.PrepReqParams(reqParams));
4627
+ const urlParams = new URLSearchParams();
4628
+ if (expandLocation) {
4629
+ urlParams.append("$expand", "location");
4630
+ }
4631
+ if (entityTypeId) {
4632
+ urlParams.append("BruceEntityType", entityTypeId);
4633
+ }
4634
+ const data = yield api.GET(`entity/${entityId}?${urlParams.toString()}`, Api.PrepReqParams(reqParams));
4745
4635
  res({
4746
4636
  entity: data
4747
4637
  });