Skip to content

Commit

Permalink
Expose utility function to enable BitInt serialization in consumer app
Browse files Browse the repository at this point in the history
  • Loading branch information
axelboc committed Sep 9, 2024
1 parent 3c01b05 commit 4bf0d55
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 1 deletion.
4 changes: 3 additions & 1 deletion apps/demo/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import './styles.css'; // global styles

import { assertNonNull } from '@h5web/app';
import { assertNonNull, enableBigIntSerialization } from '@h5web/app';
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';

import DemoApp from './DemoApp';

enableBigIntSerialization(); // for `RawVis` and `MetadataViewer`

const rootElem = document.querySelector('#root');
assertNonNull(rootElem);

Expand Down
38 changes: 38 additions & 0 deletions packages/app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,44 @@ import { getFeedbackMailto } from '@h5web/app';
}} />
```

#### `enableBigIntSerialization`

Invoke this function before rendering your application to allow the _Raw_
visualization and metadata inspector to serialize and display
[big integers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#bigint_type):

```jsx
enableBigIntSerialization();
createRoot(document.querySelector('#root')).render(<MyApp />);
```

This is recommended if you work with a provider that supports 64-bit integers —
i.e. one that may provide dataset and attribute values that include primitive
`bigint` numbers — currently only [`MockProvider`](#mockprovider).

The _Raw_ visualization and metadata inspector rely on `JSON.stringify()` to
render dataset and attribute values. By default, `JSON.stringify()` does not
know how to serialize `bigint` numbers and throws an error if it encounters one.
`enableBigIntSerialization()` teaches `JSON.stringify()` to convert big integers
to strings:

```js
> JSON.stringify(123n);
TypeError: Do not know how to serialize a BigInt

> enableBigIntSerialization();
> JSON.stringify(123n);
"123n"
```

> The `n` suffix (i.e. the same suffix used for `bigint` literals as
> demonstrated above) is added to help distinguish big integer strings from
> other strings.
> If you're application already implements `bigint` serialization, you don't
> need to call `enableBigIntSerialization()`. Doing so would override the
> existing implementation, which might have unintended effects.
### Context

The viewer component `App` communicates with its wrapping data provider through
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export { default as MockProvider } from './providers/mock/MockProvider';
export { default as HsdsProvider } from './providers/hsds/HsdsProvider';
export { default as H5GroveProvider } from './providers/h5grove/H5GroveProvider';

export { enableBigIntSerialization } from './utils';
export { getFeedbackMailto } from './breadcrumbs/utils';
export type { FeedbackContext } from './breadcrumbs/models';
export type { ExportFormat, ExportURL } from './providers/models';
Expand Down
10 changes: 10 additions & 0 deletions packages/app/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,13 @@ import type { AttrName } from './providers/models';
export function hasAttribute(entity: Entity, attributeName: AttrName) {
return entity.attributes.some((attr) => attr.name === attributeName);
}

export function enableBigIntSerialization(): void {
// eslint-disable-next-line no-extend-native
Object.defineProperty(BigInt.prototype, 'toJSON', {
configurable: true,
value: function toJSON(this: bigint) {
return `${this.toString()}n`;
},
});
}

0 comments on commit 4bf0d55

Please sign in to comment.