Skip to content

Commit

Permalink
Add support for compressing arbitrary URLs.
Browse files Browse the repository at this point in the history
Add support for compressing arbitrary URLs. Any id which is in the
`appContextMap` will be compressed as a single number before using other
URL codecs.
  • Loading branch information
davidlehn committed Dec 21, 2023
1 parent eba334a commit 29bf4e1
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 4 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# @digitalbazaar/cborld ChangeLog

## 6.1.0 - 2023-xx-xx

### Added
- Add support for compressing arbitrary URLs. Any id which is in the
`appContextMap` will be compressed as a single number before using other URL
codecs.

## 6.0.3 - 2023-12-19

### Fixed
Expand Down
36 changes: 36 additions & 0 deletions lib/codecs/AppUrlDecoder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*!
* Copyright (c) 2021-2023 Digital Bazaar, Inc. All rights reserved.
*/
import {CborldDecoder} from './CborldDecoder.js';
import {CborldError} from '../CborldError.js';

const ID = 1026;

export class AppUrlDecoder extends CborldDecoder {
constructor({reverseAppContextMap} = {}) {
super();
this.reverseAppContextMap = reverseAppContextMap;
}

decode({value} = {}) {
// handle compressed app URL
const url = this.reverseAppContextMap.get(value[1]);
if(url === undefined) {
throw new CborldError(
'ERR_UNDEFINED_COMPRESSED_APP_URL',
`Undefined compressed context "${value}".`);
}
return url;
}

static createDecoder({value, transformer} = {}) {
if(!(Array.isArray(value) && value.length === 2)) {
return false;
}
if(!(value[0] === ID)) {
return false;
}
const {reverseAppContextMap} = transformer;
return new AppUrlDecoder({reverseAppContextMap});
}
}
35 changes: 35 additions & 0 deletions lib/codecs/AppUrlEncoder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*!
* Copyright (c) 2021-2023 Digital Bazaar, Inc. All rights reserved.
*/
import {Token, Type} from 'cborg';
import {CborldEncoder} from './CborldEncoder.js';

const ID = 1026;

export class AppUrlEncoder extends CborldEncoder {
constructor({value, appContextMap} = {}) {
super();
this.value = value;
this.appContextMap = appContextMap;
}

encode() {
const {value} = this;
// FIXME: handle errors (shouldn't happen if called correctly)
const id = this.appContextMap.get(value);
const entries = [
new Token(Type.uint, ID),
new Token(Type.uint, id)
];
return [new Token(Type.array, entries.length), entries];
}

static createEncoder({value, transformer} = {}) {
// FIXME: needed?
if(typeof value !== 'string') {
return false;
}
const {appContextMap} = transformer;
return new AppUrlEncoder({value, appContextMap});
}
}
9 changes: 6 additions & 3 deletions lib/codecs/UriDecoder.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*!
* Copyright (c) 2021-2023 Digital Bazaar, Inc. All rights reserved.
*/
import {AppUrlDecoder} from './AppUrlDecoder.js';
import {Base58DidUrlDecoder} from './Base58DidUrlDecoder.js';
import {CborldDecoder} from './CborldDecoder.js';
import {HttpUrlDecoder} from './HttpUrlDecoder.js';
Expand All @@ -11,16 +12,18 @@ const SCHEME_ID_TO_DECODER = new Map([
[2, HttpUrlDecoder],
[3, UuidUrnDecoder],
[1024, Base58DidUrlDecoder],
[1025, Base58DidUrlDecoder]
[1025, Base58DidUrlDecoder],
// FIXME: encdeds as 3 bytes, may want to use a lower id
[1026, AppUrlDecoder]
]);

export class UriDecoder extends CborldDecoder {
static createDecoder({value} = {}) {
static createDecoder({value, transformer} = {}) {
if(!(Array.isArray(value) || value.length > 1)) {
return false;
}

const DecoderClass = SCHEME_ID_TO_DECODER.get(value[0]);
return DecoderClass && DecoderClass.createDecoder({value});
return DecoderClass && DecoderClass.createDecoder({value, transformer});
}
}
8 changes: 7 additions & 1 deletion lib/codecs/UriEncoder.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*!
* Copyright (c) 2021-2023 Digital Bazaar, Inc. All rights reserved.
*/
import {AppUrlEncoder} from './AppUrlEncoder.js';
import {Base58DidUrlEncoder} from './Base58DidUrlEncoder.js';
import {CborldEncoder} from './CborldEncoder.js';
import {HttpUrlEncoder} from './HttpUrlEncoder.js';
Expand All @@ -15,11 +16,16 @@ const SCHEME_TO_ENCODER = new Map([
]);

export class UriEncoder extends CborldEncoder {
static createEncoder({value} = {}) {
static createEncoder({value, transformer} = {}) {
if(typeof value !== 'string') {
return false;
}

const {appContextMap} = transformer;
if(appContextMap.has(value)) {
return AppUrlEncoder.createEncoder({value, transformer});
}

// get full colon-delimited prefix
let scheme;
try {
Expand Down

0 comments on commit 29bf4e1

Please sign in to comment.