Skip to content

Commit b6580c5

Browse files
committed
fixup: review suggestions
1 parent e636479 commit b6580c5

File tree

5 files changed

+87
-79
lines changed

5 files changed

+87
-79
lines changed

packages/marshal/NEWS.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ User-visible changes in `@endo/marshal`:
22

33
# next release
44

5-
- JavaScript's relational comparison operators like `<` compare strings by lexicographic UTF16 code unit order, which is exposes an internal representational detail not relevant to the string's meaning as a Unicode string. Previously, `compareRank` and associated functions compared strings using this JavaScript-native comparison. Now `compareRank` and associated functions compare strings by lexicographic Unicode Code Point order. ***This change only affects strings containing so-called supplementary characters, i.e., those whose Unicode character code does not fit in 16 bits***.
5+
- JavaScript's relational comparison operators like `<` compare strings by lexicographic UTF16 code unit order, which exposes an internal representational detail not relevant to the string's meaning as a Unicode string. Previously, `compareRank` and associated functions compared strings using this JavaScript-native comparison. Now `compareRank` and associated functions compare strings by lexicographic Unicode Code Point order. ***This change only affects strings containing so-called supplementary characters, i.e., those whose Unicode character code does not fit in 16 bits***.
66
- This release does not change the `encodePassable` encoding. But now, when we say it is order preserving, we need to be careful about which order we mean. `encodePassable` is rank-order preserving when the encoded strings are compared using `compareRank`.
77
- The key order of strings defined by the @endo/patterns module is still defined to be the same as the rank ordering of those strings. So this release changes key order among strings to also be lexicographic comparison of Unicode Code Points. To accommodate this change, you may need to adapt applications that relied on key-order being the same as JS native order. This could include the use of any patterns expressing key inequality tests, like `M.gte(string)`.
88
- These string ordering changes brings Endo into conformance with any string ordering components of the OCapN standard.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/* eslint-disable no-bitwise, @endo/restrict-comparison-operands */
2+
import { Fail, q } from '@endo/errors';
3+
4+
import {
5+
makeEncodePassable,
6+
makeDecodePassable,
7+
} from '../src/encodePassable.js';
8+
import { compareRank, makeComparatorKit } from '../src/rankOrder.js';
9+
10+
const buffers = {
11+
__proto__: null,
12+
r: [],
13+
'?': [],
14+
'!': [],
15+
};
16+
const resetBuffers = () => {
17+
buffers.r = [];
18+
buffers['?'] = [];
19+
buffers['!'] = [];
20+
};
21+
const cursors = {
22+
__proto__: null,
23+
r: 0,
24+
'?': 0,
25+
'!': 0,
26+
};
27+
const resetCursors = () => {
28+
cursors.r = 0;
29+
cursors['?'] = 0;
30+
cursors['!'] = 0;
31+
};
32+
33+
const encodeThing = (prefix, r) => {
34+
buffers[prefix].push(r);
35+
// With this encoding, all things with the same prefix have the same rank
36+
return prefix;
37+
};
38+
39+
const decodeThing = (prefix, e) => {
40+
prefix === e ||
41+
Fail`expected encoding ${q(e)} to simply be the prefix ${q(prefix)}`;
42+
(cursors[prefix] >= 0 && cursors[prefix] < buffers[prefix].length) ||
43+
Fail`while decoding ${q(e)}, expected cursors[${q(prefix)}], i.e., ${q(
44+
cursors[prefix],
45+
)} <= ${q(buffers[prefix].length)}`;
46+
const thing = buffers[prefix][cursors[prefix]];
47+
cursors[prefix] += 1;
48+
return thing;
49+
};
50+
51+
const encodePassableInternal = makeEncodePassable({
52+
encodeRemotable: r => encodeThing('r', r),
53+
encodePromise: p => encodeThing('?', p),
54+
encodeError: er => encodeThing('!', er),
55+
});
56+
57+
export const encodePassable = passable => {
58+
resetBuffers();
59+
return encodePassableInternal(passable);
60+
};
61+
62+
const decodePassableInternal = makeDecodePassable({
63+
decodeRemotable: e => decodeThing('r', e),
64+
decodePromise: e => decodeThing('?', e),
65+
decodeError: e => decodeThing('!', e),
66+
});
67+
68+
export const decodePassable = encoded => {
69+
resetCursors();
70+
return decodePassableInternal(encoded);
71+
};
72+
73+
const compareRemotables = (x, y) =>
74+
compareRank(encodeThing('r', x), encodeThing('r', y));
75+
76+
export const { comparator: compareFull } = makeComparatorKit(compareRemotables);

packages/marshal/test/test-encodePassable.js

+8-76
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,21 @@
1-
// @ts-nocheck
21
/* eslint-disable no-bitwise, @endo/restrict-comparison-operands */
32
// eslint-disable-next-line import/order
43
import { test } from './prepare-test-env-ava.js';
54

6-
// eslint-disable-next-line import/order
75
import { fc } from '@fast-check/ava';
86
import { arbPassable } from '@endo/pass-style/tools.js';
9-
import { Fail, q } from '@endo/errors';
7+
import { Fail } from '@endo/errors';
108

119
// eslint-disable-next-line import/no-extraneous-dependencies
1210

13-
import {
14-
makeEncodePassable,
15-
makeDecodePassable,
16-
} from '../src/encodePassable.js';
17-
import { compareRank, makeComparatorKit } from '../src/rankOrder.js';
11+
import { compareRank } from '../src/rankOrder.js';
1812
import { sample } from './test-rankOrder.js';
1913

20-
const buffers = {
21-
__proto__: null,
22-
r: [],
23-
'?': [],
24-
'!': [],
25-
};
26-
const resetBuffers = () => {
27-
buffers.r = [];
28-
buffers['?'] = [];
29-
buffers['!'] = [];
30-
};
31-
const cursors = {
32-
__proto__: null,
33-
r: 0,
34-
'?': 0,
35-
'!': 0,
36-
};
37-
const resetCursors = () => {
38-
cursors.r = 0;
39-
cursors['?'] = 0;
40-
cursors['!'] = 0;
41-
};
42-
43-
const encodeThing = (prefix, r) => {
44-
buffers[prefix].push(r);
45-
// With this encoding, all things with the same prefix have the same rank
46-
return prefix;
47-
};
48-
49-
const decodeThing = (prefix, e) => {
50-
prefix === e ||
51-
Fail`expected encoding ${q(e)} to simply be the prefix ${q(prefix)}`;
52-
(cursors[prefix] >= 0 && cursors[prefix] < buffers[prefix].length) ||
53-
Fail`while decoding ${q(e)}, expected cursors[${q(prefix)}], i.e., ${q(
54-
cursors[prefix],
55-
)} <= ${q(buffers[prefix].length)}`;
56-
const thing = buffers[prefix][cursors[prefix]];
57-
cursors[prefix] += 1;
58-
return thing;
59-
};
60-
61-
const compareRemotables = (x, y) =>
62-
compareRank(encodeThing('r', x), encodeThing('r', y));
63-
64-
const encodePassableInternal = makeEncodePassable({
65-
encodeRemotable: r => encodeThing('r', r),
66-
encodePromise: p => encodeThing('?', p),
67-
encodeError: er => encodeThing('!', er),
68-
});
69-
70-
export const encodePassable = passable => {
71-
resetBuffers();
72-
return encodePassableInternal(passable);
73-
};
74-
75-
const decodePassableInternal = makeDecodePassable({
76-
decodeRemotable: e => decodeThing('r', e),
77-
decodePromise: e => decodeThing('?', e),
78-
decodeError: e => decodeThing('!', e),
79-
});
80-
81-
export const decodePassable = encoded => {
82-
resetCursors();
83-
return decodePassableInternal(encoded);
84-
};
85-
86-
const { comparator: compareFull } = makeComparatorKit(compareRemotables);
14+
import {
15+
encodePassable,
16+
decodePassable,
17+
compareFull,
18+
} from './encodePassable-for-testing.js';
8719

8820
const asNumber = new Float64Array(1);
8921
const asBits = new BigUint64Array(asNumber.buffer);
@@ -99,7 +31,7 @@ const getNaN = (hexEncoding = '0008000000000000') => {
9931

10032
const NegativeNaN = getNaN('ffffffffffffffff');
10133

102-
/** @type {[Key, string][]} */
34+
/** @type {[number | bigint, string][]} */
10335
const goldenPairs = harden([
10436
[1, 'fbff0000000000000'],
10537
[-1, 'f400fffffffffffff'],

packages/marshal/test/test-string-rank-order.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { test } from './prepare-test-env-ava.js';
22

33
import { compareRank } from '../src/rankOrder.js';
4-
import { encodePassable } from './test-encodePassable.js';
4+
import { encodePassable } from './encodePassable-for-testing.js';
55

66
/**
77
* Essentially a ponyfill for Array.prototype.toSorted, for use before

packages/patterns/NEWS.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ User-visible changes in `@endo/patterns`:
22

33
# next release
44

5-
- JavaScript's relational comparison operators like `<` compare strings by lexicographic UTF16 code unit order, which is exposes an internal representational detail not relevant to the string's meaning as a Unicode string. Previously, `compareKeys` and associated functions compared strings using this JavaScript-native comparison. Now `compareKeys` and associated functions compare strings by lexicographic Unicode Code Point order. ***This change only affects strings containing so-called supplementary characters, i.e., those whose Unicode character code does not fit in 16 bits***.
5+
- JavaScript's relational comparison operators like `<` compare strings by lexicographic UTF16 code unit order, which exposes an internal representational detail not relevant to the string's meaning as a Unicode string. Previously, `compareKeys` and associated functions compared strings using this JavaScript-native comparison. Now `compareKeys` and associated functions compare strings by lexicographic Unicode Code Point order. ***This change only affects strings containing so-called supplementary characters, i.e., those whose Unicode character code does not fit in 16 bits***.
66
- See the NEWS.md of @endo/marshal for more on this change.
77

88
# v0.2.6 (2023-09-11)

0 commit comments

Comments
 (0)