Skip to content

Commit

Permalink
Make interfaces for compress/decompress more clear.
Browse files Browse the repository at this point in the history
- Separate responsibilities for transforming JSON-LD <=> CBOR
  abstract form from serializing / deserializing it.
  • Loading branch information
dlongley committed Aug 11, 2024
1 parent c5f5c74 commit fc14f1c
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 55 deletions.
28 changes: 3 additions & 25 deletions lib/Compressor.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
/*!
* Copyright (c) 2021-2024 Digital Bazaar, Inc. All rights reserved.
*/
import * as cborg from 'cborg';
import {CborldEncoder} from './codecs/CborldEncoder.js';
import {ContextEncoder} from './codecs/ContextEncoder.js';
import {ContextProcessor} from './ContextProcessor.js';
import {inspect} from './util.js';
import {KEYWORDS_TABLE} from './tables.js';
import {Transformer} from './Transformer.js';
import {ValueEncoder} from './codecs/ValueEncoder.js';

const CONTEXT_TERM_ID = KEYWORDS_TABLE.get('@context');
const CONTEXT_TERM_ID_PLURAL = CONTEXT_TERM_ID + 1;

// override cborg object encoder to use cborld encoders
const typeEncoders = {
Object(obj) {
if(obj instanceof CborldEncoder) {
return obj.encode({obj});
}
}
};

export class Compressor {
/**
* Creates a new Compressor for generating compressed CBOR-LD from a
Expand Down Expand Up @@ -54,23 +42,13 @@ export class Compressor {
* @param {object} options - The options to use.
* @param {object} options.jsonldDocument - The JSON-LD Document to convert
* to CBOR-LD bytes.
* @param {diagnosticFunction} [options.diagnose] - A function that, if
* provided, is called with diagnostic information.
*
* @returns {Promise<Uint8Array>} - The compressed CBOR-LD bytes.
* @returns {Map|Array} - The transform map(s) to produce CBOR-LD bytes.
*/
async compress({jsonldDocument, diagnose} = {}) {
async compress({jsonldDocument} = {}) {
// FIXME: remove unused reset feature
this.transformer.reset();

const transformMaps = await this._createTransformMaps({jsonldDocument});
if(diagnose) {
diagnose('Diagnostic CBOR-LD compression transform map(s):');
diagnose(inspect(transformMaps, {depth: null, colors: true}));
}
return cborg.encode(transformMaps, {typeEncoders});
}

async _createTransformMaps({jsonldDocument}) {
// handle single or multiple JSON-LD docs
const transformMaps = [];
const isArray = Array.isArray(jsonldDocument);
Expand Down
18 changes: 4 additions & 14 deletions lib/Decompressor.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
/*!
* Copyright (c) 2021-2024 Digital Bazaar, Inc. All rights reserved.
*/
import * as cborg from 'cborg';
import {KEYWORDS_TABLE, reverseMap} from './tables.js';
import {CborldError} from './CborldError.js';
import {ContextDecoder} from './codecs/ContextDecoder.js';
import {ContextProcessor} from './ContextProcessor.js';
import {inspect} from './util.js';
import {Transformer} from './Transformer.js';
import {ValueDecoder} from './codecs/ValueDecoder.js';

Expand Down Expand Up @@ -55,23 +53,15 @@ export class Decompressor {
* Decompresses the given CBOR-LD byte array to a JSON-LD document.
*
* @param {object} options - The options to use.
* @param {Uint8Array} options.compressedBytes - The CBOR-LD compressed
* bytes that follow the compressed CBOR-LD CBOR tag.
* @param {diagnosticFunction} [options.diagnose] - A function that, if
* provided, is called with diagnostic information.
* @param {Map|Array} options.transformMap - The transform map(s) to
* convert CBOR-LD to JSON-LD.
*
* @returns {Promise<object>} - The JSON-LD document.
*/
async decompress({compressedBytes, diagnose} = {}) {
async decompress({transformMap} = {}) {
// FIXME: remove unused reset feature
this.transformer.reset();

// decoded output could be one or more transform maps
const transformMap = cborg.decode(compressedBytes, {useMaps: true});
if(diagnose) {
diagnose('Diagnostic CBOR-LD decompression transform map(s):');
diagnose(inspect(transformMap, {depth: null, colors: true}));
}

// handle single or multiple JSON-LD docs
const results = [];
const isArray = Array.isArray(transformMap);
Expand Down
21 changes: 14 additions & 7 deletions lib/decode.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,27 @@ export async function decode({
}
const {suffix, isLegacy} = _getSuffix({cborldBytes});
const isCompressed = _checkCompressionMode({cborldBytes, isLegacy});
if(!isCompressed) {
return cborg.decode(suffix, {useMaps: false});
}

// decoded output should be one or more transform maps
// FIXME: `transformMap` is an abstract representation of CBOR-LD, might
// be good to rename it
const transformMap = cborg.decode(suffix, {useMaps: true});
if(diagnose) {
diagnose('Diagnostic CBOR-LD decompression transform map(s):');
diagnose(inspect(transformMap, {depth: null, colors: true}));
}

// decompress CBOR-LD => JSON-LD
const decompressor = _createDecompressor({
isLegacy,
documentLoader,
typeTable,
appContextMap
});

if(!isCompressed) {
return cborg.decode(suffix, {useMaps: false});
}

const result = await decompressor.decompress(
{compressedBytes: suffix, diagnose});
const result = await decompressor.decompress({transformMap});

if(diagnose) {
diagnose('Diagnostic JSON-LD result:');
Expand Down
37 changes: 28 additions & 9 deletions lib/encode.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,21 @@
*/
import * as cborg from 'cborg';
import * as varint from 'varint';
import {CborldEncoder} from './codecs/CborldEncoder.js';
import {CborldError} from './CborldError.js';
import {Compressor} from './Compressor.js';
import {createLegacyTypeTable} from './tables.js';
import {inspect} from './util.js';

// override cborg object encoder to use cborld encoders
const typeEncoders = {
Object(obj) {
if(obj instanceof CborldEncoder) {
return obj.encode({obj});
}
}
};

/**
* Encodes a given JSON-LD document into a CBOR-LD byte array.
*
Expand Down Expand Up @@ -79,22 +89,31 @@ export async function encode({
}
}

const prefix = _getPrefix({isLegacy, compressionMode, registryEntryId});
const compressor = _createCompressor({
isLegacy,
appContextMap,
documentLoader,
typeTable
});
// compute CBOR-LD suffix
let suffix;
if(compressionMode === 0 || registryEntryId === 0) {
// handle uncompressed CBOR-LD
// output uncompressed CBOR-LD
suffix = cborg.encode(jsonldDocument);
} else {
suffix = await compressor.compress({jsonldDocument, diagnose});
// compress JSON-LD => CBOR-LD
const compressor = _createCompressor({
isLegacy,
appContextMap,
documentLoader,
typeTable
});
// FIXME: `transformMap` is an abstract representation of CBOR-LD, might
// be good to rename it
const transformMap = await compressor.compress({jsonldDocument});
if(diagnose) {
diagnose('Diagnostic CBOR-LD compression transform map(s):');
diagnose(inspect(transformMap, {depth: null, colors: true}));
}
suffix = cborg.encode(transformMap, {typeEncoders});
}

// concatenate prefix and suffix
const prefix = _getPrefix({isLegacy, compressionMode, registryEntryId});
const length = prefix.length + suffix.length;
const bytes = new Uint8Array(length);
bytes.set(prefix);
Expand Down

0 comments on commit fc14f1c

Please sign in to comment.