Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consolidate processing. #90

Merged
merged 44 commits into from
Jul 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
a6de691
Replace `TypedLiteralEncoder` with `TypeTableEncoder`.
dlongley Jul 13, 2024
2b98f2f
Replace `TypedLiteralDecoder` with `TypeTableDecoder`.
dlongley Jul 13, 2024
cec54c0
Handle untyped literals in type table decoder.
dlongley Jul 13, 2024
93bd373
Start refactoring to remove `_transformUntypedValue`.
dlongley Jul 14, 2024
b782511
Remove `_transformUntypedValue`.
dlongley Jul 14, 2024
e27e6e1
Improve alias checking.
dlongley Jul 14, 2024
87eabed
Consolidate value transformation code.
dlongley Jul 14, 2024
f771499
Remove unused code.
dlongley Jul 14, 2024
1a99a0c
Make create codec return values consistent.
dlongley Jul 14, 2024
7344652
Handle recursing into array of arrays.
dlongley Jul 14, 2024
b66c6f8
Remove circular dependencies.
dlongley Jul 14, 2024
f0781cf
Consolidate code in URI codec classes.
dlongley Jul 14, 2024
b557ce7
Rename `Uri*` codecs to `Url*` codecs.
dlongley Jul 14, 2024
b54ca1d
Remove unused codecs.
dlongley Jul 14, 2024
aebd408
Move `helpers.js` to `/lib`.
dlongley Jul 14, 2024
2c3295f
Simplify decoder calls.
dlongley Jul 14, 2024
2e0ea3b
Remove special handling of `@id` aliases.
dlongley Jul 14, 2024
960ab47
Rename `aliases.type` to `typeAliases`.
dlongley Jul 14, 2024
0fdf3e5
Add new initial active context factory function.
dlongley Jul 14, 2024
0e7bdfd
Use `context` table for context codecs.
dlongley Jul 14, 2024
3766c11
Remove extra `keywordsTable` and consolidate reset functionality.
dlongley Jul 14, 2024
c669ba0
Remove unnecessary tables and simplify URL codecs.
dlongley Jul 14, 2024
f564945
Remove FIXMEs.
dlongley Jul 14, 2024
1b61aed
Simplify `XsdDate` codecs.
dlongley Jul 14, 2024
8fed76a
Fix up `XsdDateTime` codecs and remove some logging.
dlongley Jul 14, 2024
6ab46e9
Rename `typedLiteralTable` to `typeTable` (and reverse tables too).
dlongley Jul 14, 2024
f031f18
Consolidate calls to `Decompressor` construction.
dlongley Jul 14, 2024
4860b53
Replace `TYPED_LITERAL_TABLE` with `TYPE_TABLE`.
dlongley Jul 14, 2024
f6bf9ae
Rename `TypeTable*` => `Value*` codecs and consolidate alias processing.
dlongley Jul 14, 2024
2a3762a
Add FIXME.
dlongley Jul 14, 2024
3fe1626
Remove extra processing from multibase codecs.
dlongley Jul 14, 2024
2094618
Remove console logging in test.
dlongley Jul 14, 2024
7b62200
Start removing `stringTable` from tests.
dlongley Jul 14, 2024
6d31e2e
Remove string table from tests.
dlongley Jul 14, 2024
0f32a92
Remove unused context table from tests.
dlongley Jul 14, 2024
3fb7370
Remove string table from Transformer and derived classes.
dlongley Jul 14, 2024
944ceb1
Consolidate legacy type table creation code.
dlongley Jul 14, 2024
4cbeac5
Fix linting errors and remove commented code.
dlongley Jul 14, 2024
496adc9
Update changelog.
dlongley Jul 14, 2024
e432b1a
Use `ValueDecoder` in `Decompressor` when getting object types.
dlongley Jul 14, 2024
0936b21
Remove `registeredTermCodecs` and move comments to `tables.js`.
dlongley Jul 14, 2024
5f1dea3
Fix commented `data` URL tests.
dlongley Jul 14, 2024
6810611
Prepare to implement typed plain integer encoding.
dlongley Jul 14, 2024
3de0e7c
Express JSON numbers in typed-fields as bytes if subtable present.
dlongley Jul 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@
## 8.0.0 - 2024-mm-dd

### Added
- Add TypedLiteral, UntypedLiteral encoders and decoders to more generally
handle type-specific behavior such as cryptosuite string encoding as well
as pass through uncompressible untyped values.

### CHANGED
- Restructure term registry system to be more general with four tables which
can all be passed by the user during encoding and decoding:
- keywordsTable: for JSON-LD keywords (e.g. '@context', '@type')
- stringTable: for JSON-LD string values. This subsumes 'appContextMap',
as context strings can be included here, but includes arbitrary string
values as well.
- urlSchemeTable: for URL schemes (i.e. 'http://')
- typedLiteralTable: for values associated with JSON-LD types. This
subsumes type-specific codecs like the cryptosuite codec.
- Added support for passing through (without semantic compression) terms not
defined in contexts and other plain values.

### Changed
- Restructure term registry system to be more general with a type table. The
type table expresses type-namespaced tables of values that can be used when encoding and decoding. This type table (of tables) can be passed by the user
when encoding and decoding and will be given preference over any processing-
mode-specific codecs (such as multibase codecs).
The supported types include:
- context: for JSON-LD context URLs, this subsumes the old 'appContextMap'
and any contexts expressed in the old arbitrary string table as well.
- url: for any JSON-LD URL value, such as values associated with `@id`
or `@type` (or their aliases) JSON keys.
- none: for any untyped or plain literal values.
- <any JSON-LD type expressed as URL>: for any values associated with
any custom JSON-LD types.
- Restructure CBOR-LD tag system to use a range of tags where
the tag value informs what values for the tables above should be used
via a registry. Legacy tags (0x0501) are still supported, and new tags are
Expand Down
129 changes: 47 additions & 82 deletions lib/Compressor.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,16 @@
/*!
* Copyright (c) 2021-2023 Digital Bazaar, Inc. All rights reserved.
* Copyright (c) 2021-2024 Digital Bazaar, Inc. All rights reserved.
*/
import * as cborg from 'cborg';
import {
FIRST_CUSTOM_TERM_ID,
KEYWORDS_TABLE,
URL_SCHEME_TABLE
KEYWORDS_TABLE
} from './tables.js';
import {CborldEncoder} from './codecs/CborldEncoder.js';
import {ContextEncoder} from './codecs/ContextEncoder.js';
import {inspect} from './util.js';

import {MultibaseEncoder} from './codecs/MultibaseEncoder.js';
import {Transformer} from './Transformer.js';
import {TypedLiteralEncoder} from './codecs/TypedLiteralEncoder.js';
import {UntypedLiteralEncoder} from './codecs/UntypedLiteralEncoder.js';
import {UriEncoder} from './codecs/UriEncoder.js';
import {VocabTermEncoder} from './codecs/VocabTermEncoder.js';
import {XsdDateEncoder} from './codecs/XsdDateEncoder.js';
import {XsdDateTimeEncoder} from './codecs/XsdDateTimeEncoder.js';

export const TYPE_ENCODERS = new Map([
['@id', UriEncoder],
['@vocab', VocabTermEncoder],
['https://w3id.org/security#multibase', MultibaseEncoder],
['http://www.w3.org/2001/XMLSchema#date', XsdDateEncoder],
['http://www.w3.org/2001/XMLSchema#dateTime', XsdDateTimeEncoder]
]);
import {ValueEncoder} from './codecs/ValueEncoder.js';

const CONTEXT_TERM_ID = KEYWORDS_TABLE.get('@context');
const CONTEXT_TERM_ID_PLURAL = CONTEXT_TERM_ID + 1;
Expand All @@ -49,24 +33,13 @@ export class Compressor extends Transformer {
* @param {object} options - The options to use.
* @param {documentLoaderFunction} options.documentLoader -The document
* loader to use when resolving JSON-LD Context URLs.
* @param {Map} options.stringTable - A map of string values and
* their associated CBOR-LD integer values.
* @param {Map} options.typedLiteralTable - A map of JSON-LD types
* to maps that map values of that type to their associated CBOR-LD
* integer values.
* @param {Map} options.typeTable - A map of possible value types, including
* `context`, `url`, `none`, and any JSON-LD type, each of which maps to
* another map of values of that type to their associated CBOR-LD integer
* values.
*/
constructor({
documentLoader,
stringTable,
typedLiteralTable
} = {}) {
super({
documentLoader,
stringTable,
typedLiteralTable
});
this.keywordsTable = new Map(KEYWORDS_TABLE);
this.urlSchemeTable = new Map(URL_SCHEME_TABLE);
constructor({documentLoader, typeTable} = {}) {
super({documentLoader, typeTable});
}

/**
Expand All @@ -82,6 +55,8 @@ export class Compressor extends Transformer {
* @returns {Promise<Uint8Array>} - The compressed CBOR-LD bytes.
*/
async compress({jsonldDocument, diagnose} = {}) {
this._reset();

const transformMaps = await this._createTransformMaps({jsonldDocument});
if(diagnose) {
diagnose('Diagnostic CBOR-LD compression transform map(s):');
Expand All @@ -91,9 +66,6 @@ export class Compressor extends Transformer {
}

async _createTransformMaps({jsonldDocument}) {
// initialize state
this._reset();

// handle single or multiple JSON-LD docs
const transformMaps = [];
const isArray = Array.isArray(jsonldDocument);
Expand All @@ -118,8 +90,7 @@ export class Compressor extends Transformer {
const isArray = Array.isArray(context);
const contexts = isArray ? context : [context];
for(const value of contexts) {
const encoder = ContextEncoder.createEncoder(
{value, transformer: this});
const encoder = ContextEncoder.createEncoder({value, transformer: this});
entries.push(encoder || value);
}
const id = isArray ? CONTEXT_TERM_ID_PLURAL : CONTEXT_TERM_ID;
Expand Down Expand Up @@ -158,51 +129,53 @@ export class Compressor extends Transformer {
return entries;
}

_getObjectTypes({obj, typeTerms}) {
const objectTypes = new Set();
for(const term of typeTerms) {
const types = obj[term];
if(types !== undefined) {
if(Array.isArray(types)) {
types.forEach(objectTypes.add, objectTypes);
} else {
objectTypes.add(types);
}
}
}
return objectTypes;
}

_reset() {
this.contextMap = new Map();
this.nextTermId = FIRST_CUSTOM_TERM_ID;
this.termToId = this.keywordsTable;
}

_transformObjectId({transformMap, termInfo, value}) {
const {termId} = termInfo;
const encoder = UriEncoder.createEncoder(
{value, transformer: this, termInfo});
transformMap.set(termId, encoder || value);
}

_transformObjectType({transformMap, termInfo, value}) {
const {termId, plural} = termInfo;
const values = plural ? value : [value];
const entries = [];
for(const value of values) {
const encoder = VocabTermEncoder.createEncoder(
{value, transformer: this, termInfo});
entries.push(encoder || value);
}
transformMap.set(termId, plural ? entries : entries[0]);
this.termToId = new Map(KEYWORDS_TABLE);
}

_transformTypedValue({entries, termType, value, termInfo}) {
const encoder = TypedLiteralEncoder.createEncoder({
value,
transformer: this,
termType
}) || TYPE_ENCODERS.get(termType)?.createEncoder({
value,
transformer: this,
termInfo
});
if(encoder) {
entries.push(encoder);
return true;
_transformValue({entries, termType, value, termInfo}) {
if(typeof value === 'object') {
return;
}
const encoder = ValueEncoder.createEncoder(
{value, transformer: this, termInfo, termType});
entries.push(encoder ?? value);
return true;
}

async _transformArray({entries, contextStack, value}) {
// recurse into array
const children = [];
for(const obj of value) {
if(Array.isArray(obj)) {
// recurse into array of arrays
await this._transformArray(
{entries: children, contextStack, value: obj});
continue;
}
// handle non-object
if(!(obj && typeof obj === 'object')) {
children.push(obj);
continue;
}
// handle object
const childMap = new Map();
children.push(childMap);
await this._transform({obj, transformMap: childMap, contextStack});
Expand All @@ -217,14 +190,6 @@ export class Compressor extends Transformer {
await this._transform({obj: value, transformMap, contextStack});
}

async _transformUntypedValue({entries, value}) {
const encoder = UntypedLiteralEncoder.createEncoder({
value,
transformer: this
});
entries.push(encoder);
}

_assignEntries({entries, transformMap, termInfo}) {
const {termId, plural} = termInfo;
transformMap.set(termId, plural ? entries : entries[0]);
Expand Down
Loading
Loading