@milaboratories/pl-client 2.8.2 → 2.9.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milaboratories/pl-client",
3
- "version": "2.8.2",
3
+ "version": "2.9.1",
4
4
  "engines": {
5
5
  "node": ">=20.3.0"
6
6
  },
@@ -32,8 +32,8 @@
32
32
  "undici": "~7.5.0",
33
33
  "utility-types": "^3.11.0",
34
34
  "yaml": "^2.7.0",
35
- "@milaboratories/ts-helpers": "^1.1.7",
36
- "@milaboratories/pl-http": "^1.1.2"
35
+ "@milaboratories/pl-http": "^1.1.2",
36
+ "@milaboratories/ts-helpers": "^1.3.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "typescript": "~5.5.4",
@@ -17,6 +17,7 @@ import {
17
17
  MaxTxId,
18
18
  isLocalResourceId,
19
19
  extractBasicResourceData,
20
+ isNullResourceId,
20
21
  } from './types';
21
22
  import type {
22
23
  ClientMessageRequest,
@@ -28,7 +29,7 @@ import { TxAPI_Open_Request_WritableTx } from '../proto/github.com/milaboratory/
28
29
  import type { NonUndefined } from 'utility-types';
29
30
  import { toBytes } from '../util/util';
30
31
  import { fieldTypeToProto, protoToField, protoToResource } from './type_conversion';
31
- import { notEmpty } from '@milaboratories/ts-helpers';
32
+ import { deepFreeze, notEmpty } from '@milaboratories/ts-helpers';
32
33
  import { isNotFoundError } from './errors';
33
34
  import type { FinalResourceDataPredicate } from './final';
34
35
  import type { LRUCache } from 'lru-cache';
@@ -85,6 +86,10 @@ export function isResource(ref: AnyRef): ref is AnyResourceRef {
85
86
  );
86
87
  }
87
88
 
89
+ export function isResourceId(ref: AnyRef): ref is ResourceId {
90
+ return typeof ref === 'bigint' && !isLocalResourceId(ref) && !isNullResourceId(ref);
91
+ }
92
+
88
93
  export function isFieldRef(ref: AnyFieldRef): ref is FieldRef {
89
94
  return isResourceRef(ref.resourceId);
90
95
  }
@@ -535,6 +540,7 @@ export class PlTransaction {
535
540
  // we will cache only final resource data states
536
541
  // caching result even if we were ignore the cache
537
542
  if (!isResourceRef(rId) && !isLocalResourceId(rId) && this.finalPredicate(result)) {
543
+ deepFreeze(result);
538
544
  const fromCache = this.sharedResourceDataCache.get(rId);
539
545
  if (fromCache) {
540
546
  if (loadFields && !fromCache.data) {
@@ -543,15 +549,17 @@ export class PlTransaction {
543
549
  fromCache.cacheTxOpenTimestamp = this.txOpenTimestamp;
544
550
  }
545
551
  } else {
552
+ const basicData = extractBasicResourceData(result);
553
+ deepFreeze(basicData);
546
554
  if (loadFields)
547
555
  this.sharedResourceDataCache.set(rId, {
548
- basicData: extractBasicResourceData(result),
556
+ basicData,
549
557
  data: result,
550
558
  cacheTxOpenTimestamp: this.txOpenTimestamp,
551
559
  });
552
560
  else
553
561
  this.sharedResourceDataCache.set(rId, {
554
- basicData: extractBasicResourceData(result),
562
+ basicData,
555
563
  data: undefined,
556
564
  cacheTxOpenTimestamp: this.txOpenTimestamp,
557
565
  });
package/src/core/types.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { notEmpty } from '@milaboratories/ts-helpers';
1
+ import { cachedDeserialize, notEmpty } from '@milaboratories/ts-helpers';
2
2
 
3
3
  // more details here: https://egghead.io/blog/using-branded-types-in-typescript
4
4
  declare const __resource_id_type__: unique symbol;
@@ -118,7 +118,7 @@ export function extractBasicResourceData(rd: ResourceData): BasicResourceData {
118
118
 
119
119
  export const jsonToData = (data: unknown) => Buffer.from(JSON.stringify(data));
120
120
 
121
- export const resDataToJson = (res: ResourceData) => JSON.parse(notEmpty(res.data).toString());
121
+ export const resDataToJson = (res: ResourceData) => cachedDeserialize(notEmpty(res.data));
122
122
 
123
123
  export type ResourceData = BasicResourceData & {
124
124
  readonly fields: FieldData[];
@@ -1,7 +1,7 @@
1
1
  import type { PlTransaction } from '../core/transaction';
2
2
  import type { FieldData, OptionalResourceId } from '../core/types';
3
3
  import { isNotNullResourceId } from '../core/types';
4
- import { notEmpty } from '@milaboratories/ts-helpers';
4
+ import { cachedDeserialize, notEmpty } from '@milaboratories/ts-helpers';
5
5
 
6
6
  export interface ValErr {
7
7
  valueId: OptionalResourceId;
@@ -18,7 +18,12 @@ export async function valErr(tx: PlTransaction, f: FieldData): Promise<ValErr> {
18
18
 
19
19
  if (isNotNullResourceId(f.error)) {
20
20
  const e = await tx.getResourceData(f.error, true);
21
- result.error = JSON.parse(notEmpty(e.data).toString());
21
+ const deserializationResult = cachedDeserialize(notEmpty(e.data));
22
+ if (typeof deserializationResult !== 'string') {
23
+ const dataStr = notEmpty(e.data).toString();
24
+ throw new Error(`Unexpected error structure: ${dataStr.substring(0, Math.min(dataStr.length, 100))}...`);
25
+ }
26
+ result.error = deserializationResult;
22
27
  }
23
28
 
24
29
  return result;