msgpackr 1.11.12 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/pack.js CHANGED
@@ -1,139 +1,138 @@
1
- import { Unpackr, mult10, C1Type, typedArrays, addExtension as unpackAddExtension } from './unpack.js'
2
- let textEncoder
1
+ import { Unpackr, mult10, C1Type, typedArrays, addExtension as unpackAddExtension } from './unpack.js';
2
+ let textEncoder;
3
3
  try {
4
- textEncoder = new TextEncoder()
4
+ textEncoder = new TextEncoder();
5
5
  } catch (error) {}
6
- let extensions, extensionClasses
7
- const hasNodeBuffer = typeof Buffer !== 'undefined'
6
+ let extensions, extensionClasses;
7
+ const hasNodeBuffer = typeof Buffer !== 'undefined';
8
8
  const ByteArrayAllocate = hasNodeBuffer ?
9
- function(length) { return Buffer.allocUnsafeSlow(length) } : Uint8Array
10
- const ByteArray = hasNodeBuffer ? Buffer : Uint8Array
11
- const MAX_BUFFER_SIZE = hasNodeBuffer ? 0x100000000 : 0x7fd00000
12
- let target, keysTarget
13
- let targetView
14
- let position = 0
15
- let safeEnd
16
- let bundledStrings = null
17
- let writeStructSlots
18
- const MAX_BUNDLE_SIZE = 0x5500 // maximum characters such that the encoded bytes fits in 16 bits.
19
- const hasNonLatin = /[\u0080-\uFFFF]/
20
- export const RECORD_SYMBOL = Symbol('record-id')
9
+ function(length) { return Buffer.allocUnsafeSlow(length); } : Uint8Array;
10
+ const ByteArray = hasNodeBuffer ? Buffer : Uint8Array;
11
+ const MAX_BUFFER_SIZE = hasNodeBuffer ? 0x100000000 : 0x7fd00000;
12
+ let target, keysTarget;
13
+ let targetView;
14
+ let position = 0;
15
+ let safeEnd;
16
+ let bundledStrings = null;
17
+ const MAX_BUNDLE_SIZE = 0x5500; // maximum characters such that the encoded bytes fits in 16 bits.
18
+ const hasNonLatin = /[\u0080-\uFFFF]/;
19
+ export const RECORD_SYMBOL = Symbol('record-id');
21
20
  export class Packr extends Unpackr {
22
21
  constructor(options) {
23
- super(options)
24
- this.offset = 0
25
- let typeBuffer
26
- let start
27
- let hasSharedUpdate
28
- let structures
29
- let referenceMap
22
+ super(options);
23
+ this.offset = 0;
24
+ let typeBuffer;
25
+ let start;
26
+ let hasSharedUpdate;
27
+ let structures;
28
+ let referenceMap;
30
29
  let encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position) {
31
- return target.utf8Write(string, position, target.byteLength - position)
30
+ return target.utf8Write(string, position, target.byteLength - position);
32
31
  } : (textEncoder && textEncoder.encodeInto) ?
33
32
  function(string, position) {
34
- return textEncoder.encodeInto(string, target.subarray(position)).written
35
- } : false
33
+ return textEncoder.encodeInto(string, target.subarray(position)).written;
34
+ } : false;
36
35
 
37
- let packr = this
36
+ let packr = this;
38
37
  if (!options)
39
- options = {}
40
- let isSequential = options && options.sequential
41
- let hasSharedStructures = options.structures || options.saveStructures
42
- let maxSharedStructures = options.maxSharedStructures
38
+ options = {};
39
+ let isSequential = options && options.sequential;
40
+ let hasSharedStructures = options.structures || options.saveStructures;
41
+ let maxSharedStructures = options.maxSharedStructures;
43
42
  if (maxSharedStructures == null)
44
- maxSharedStructures = hasSharedStructures ? 32 : 0
43
+ maxSharedStructures = hasSharedStructures ? 32 : 0;
45
44
  if (maxSharedStructures > 8160)
46
- throw new Error('Maximum maxSharedStructure is 8160')
45
+ throw new Error('Maximum maxSharedStructure is 8160');
47
46
  if (options.structuredClone && options.moreTypes == undefined) {
48
- this.moreTypes = true
47
+ this.moreTypes = true;
49
48
  }
50
- let maxOwnStructures = options.maxOwnStructures
49
+ let maxOwnStructures = options.maxOwnStructures;
51
50
  if (maxOwnStructures == null)
52
- maxOwnStructures = hasSharedStructures ? 32 : 64
51
+ maxOwnStructures = hasSharedStructures ? 32 : 64;
53
52
  if (!this.structures && options.useRecords != false)
54
- this.structures = []
53
+ this.structures = [];
55
54
  // two byte record ids for shared structures
56
- let useTwoByteRecords = maxSharedStructures > 32 || (maxOwnStructures + maxSharedStructures > 64)
57
- let sharedLimitId = maxSharedStructures + 0x40
58
- let maxStructureId = maxSharedStructures + maxOwnStructures + 0x40
55
+ let useTwoByteRecords = maxSharedStructures > 32 || (maxOwnStructures + maxSharedStructures > 64);
56
+ let sharedLimitId = maxSharedStructures + 0x40;
57
+ let maxStructureId = maxSharedStructures + maxOwnStructures + 0x40;
59
58
  if (maxStructureId > 8256) {
60
- throw new Error('Maximum maxSharedStructure + maxOwnStructure is 8192')
59
+ throw new Error('Maximum maxSharedStructure + maxOwnStructure is 8192');
61
60
  }
62
- let recordIdsToRemove = []
63
- let transitionsCount = 0
64
- let serializationsSinceTransitionRebuild = 0
61
+ let recordIdsToRemove = [];
62
+ let transitionsCount = 0;
63
+ let serializationsSinceTransitionRebuild = 0;
65
64
 
66
65
  this.pack = this.encode = function(value, encodeOptions) {
67
66
  if (!target) {
68
- target = new ByteArrayAllocate(8192)
69
- targetView = target.dataView || (target.dataView = new DataView(target.buffer, 0, 8192))
70
- position = 0
67
+ target = new ByteArrayAllocate(8192);
68
+ targetView = target.dataView || (target.dataView = new DataView(target.buffer, 0, 8192));
69
+ position = 0;
71
70
  }
72
- safeEnd = target.length - 10
71
+ safeEnd = target.length - 10;
73
72
  if (safeEnd - position < 0x800) {
74
73
  // don't start too close to the end,
75
- target = new ByteArrayAllocate(target.length)
76
- targetView = target.dataView || (target.dataView = new DataView(target.buffer, 0, target.length))
77
- safeEnd = target.length - 10
78
- position = 0
74
+ target = new ByteArrayAllocate(target.length);
75
+ targetView = target.dataView || (target.dataView = new DataView(target.buffer, 0, target.length));
76
+ safeEnd = target.length - 10;
77
+ position = 0;
79
78
  } else
80
- position = (position + 7) & 0x7ffffff8 // Word align to make any future copying of this buffer faster
81
- start = position
82
- if (encodeOptions & RESERVE_START_SPACE) position += (encodeOptions & 0xff)
83
- referenceMap = packr.structuredClone ? new Map() : null
79
+ position = (position + 7) & 0x7ffffff8; // Word align to make any future copying of this buffer faster
80
+ start = position;
81
+ if (encodeOptions & RESERVE_START_SPACE) position += (encodeOptions & 0xff);
82
+ referenceMap = packr.structuredClone ? new Map() : null;
84
83
  if (packr.bundleStrings && typeof value !== 'string') {
85
- bundledStrings = []
86
- bundledStrings.size = Infinity // force a new bundle start on first string
84
+ bundledStrings = [];
85
+ bundledStrings.size = Infinity; // force a new bundle start on first string
87
86
  } else
88
- bundledStrings = null
89
- structures = packr.structures
87
+ bundledStrings = null;
88
+ structures = packr.structures;
90
89
  if (structures) {
91
90
  if (structures.uninitialized)
92
- structures = packr._mergeStructures(packr.getStructures())
93
- let sharedLength = structures.sharedLength || 0
91
+ structures = packr._mergeStructures(packr.getStructures());
92
+ let sharedLength = structures.sharedLength || 0;
94
93
  if (sharedLength > maxSharedStructures) {
95
94
  //if (maxSharedStructures <= 32 && structures.sharedLength > 32) // TODO: could support this, but would need to update the limit ids
96
- throw new Error('Shared structures is larger than maximum shared structures, try increasing maxSharedStructures to ' + structures.sharedLength)
95
+ throw new Error('Shared structures is larger than maximum shared structures, try increasing maxSharedStructures to ' + structures.sharedLength);
97
96
  }
98
97
  if (!structures.transitions) {
99
98
  // rebuild our structure transitions
100
- structures.transitions = Object.create(null)
99
+ structures.transitions = Object.create(null);
101
100
  for (let i = 0; i < sharedLength; i++) {
102
- let keys = structures[i]
101
+ let keys = structures[i];
103
102
  if (!keys)
104
- continue
105
- let nextTransition, transition = structures.transitions
103
+ continue;
104
+ let nextTransition, transition = structures.transitions;
106
105
  for (let j = 0, l = keys.length; j < l; j++) {
107
- let key = keys[j]
108
- nextTransition = transition[key]
106
+ let key = keys[j];
107
+ nextTransition = transition[key];
109
108
  if (!nextTransition) {
110
- nextTransition = transition[key] = Object.create(null)
109
+ nextTransition = transition[key] = Object.create(null);
111
110
  }
112
- transition = nextTransition
111
+ transition = nextTransition;
113
112
  }
114
- transition[RECORD_SYMBOL] = i + 0x40
113
+ transition[RECORD_SYMBOL] = i + 0x40;
115
114
  }
116
- this.lastNamedStructuresLength = sharedLength
115
+ this.lastNamedStructuresLength = sharedLength;
117
116
  }
118
117
  if (!isSequential) {
119
- structures.nextId = sharedLength + 0x40
118
+ structures.nextId = sharedLength + 0x40;
120
119
  }
121
120
  }
122
121
  if (hasSharedUpdate)
123
- hasSharedUpdate = false
122
+ hasSharedUpdate = false;
124
123
  let encodingError;
125
124
  try {
126
- if (packr.randomAccessStructure && value && typeof value === 'object') {
125
+ if (packr._writeStruct && value && typeof value === 'object') {
127
126
  if (value.constructor === Object) writeStruct(value); // simple object
128
127
  else if (value.constructor !== Map && !Array.isArray(value) && !extensionClasses.some(extClass => value instanceof extClass)) {
129
128
  // allow user classes, if they don't need special handling (but do use toJSON if available)
130
129
  writeStruct(value.toJSON ? value.toJSON() : value);
131
- } else pack(value)
130
+ } else pack(value);
132
131
  } else
133
- pack(value)
132
+ pack(value);
134
133
  let lastBundle = bundledStrings;
135
134
  if (bundledStrings)
136
- writeBundles(start, pack, 0)
135
+ writeBundles(start, pack, 0);
137
136
  if (referenceMap && referenceMap.idsToInsert) {
138
137
  let idsToInsert = referenceMap.idsToInsert.sort((a, b) => a.offset > b.offset ? 1 : -1);
139
138
  let i = idsToInsert.length;
@@ -149,7 +148,7 @@ export class Packr extends Unpackr {
149
148
  if (incrementPosition >= 0) {
150
149
  // update the bundle reference now
151
150
  targetView.setUint32(lastBundle.position + start,
152
- targetView.getUint32(lastBundle.position + start) + incrementPosition)
151
+ targetView.getUint32(lastBundle.position + start) + incrementPosition);
153
152
  incrementPosition = -1; // reset
154
153
  }
155
154
  lastBundle = lastBundle.previous;
@@ -159,23 +158,23 @@ export class Packr extends Unpackr {
159
158
  if (incrementPosition >= 0 && lastBundle) {
160
159
  // update the bundle reference now
161
160
  targetView.setUint32(lastBundle.position + start,
162
- targetView.getUint32(lastBundle.position + start) + incrementPosition)
161
+ targetView.getUint32(lastBundle.position + start) + incrementPosition);
163
162
  }
164
163
  position += idsToInsert.length * 6;
165
164
  if (position > safeEnd)
166
- makeRoom(position)
167
- packr.offset = position
168
- let serialized = insertIds(target.subarray(start, position), idsToInsert)
169
- referenceMap = null
170
- return serialized
165
+ makeRoom(position);
166
+ packr.offset = position;
167
+ let serialized = insertIds(target.subarray(start, position), idsToInsert);
168
+ referenceMap = null;
169
+ return serialized;
171
170
  }
172
- packr.offset = position // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
171
+ packr.offset = position; // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
173
172
  if (encodeOptions & REUSE_BUFFER_MODE) {
174
- target.start = start
175
- target.end = position
176
- return target
173
+ target.start = start;
174
+ target.end = position;
175
+ return target;
177
176
  }
178
- return target.subarray(start, position) // position can change if we call pack again in saveStructures, so we get the buffer now
177
+ return target.subarray(start, position); // position can change if we call pack again in saveStructures, so we get the buffer now
179
178
  } catch(error) {
180
179
  encodingError = error;
181
180
  throw error;
@@ -183,336 +182,336 @@ export class Packr extends Unpackr {
183
182
  if (structures) {
184
183
  resetStructures();
185
184
  if (hasSharedUpdate && packr.saveStructures) {
186
- let sharedLength = structures.sharedLength || 0
185
+ let sharedLength = structures.sharedLength || 0;
187
186
  // we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
188
- let returnBuffer = target.subarray(start, position)
189
- let newSharedData = prepareStructures(structures, packr);
187
+ let returnBuffer = target.subarray(start, position);
188
+ let newSharedData = (packr._prepareStructures || prepareStructures)(structures, packr);
190
189
  if (!encodingError) { // TODO: If there is an encoding error, should make the structures as uninitialized so they get rebuilt next time
191
190
  if (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
192
191
  // get updated structures and try again if the update failed
193
- return packr.pack(value, encodeOptions)
192
+ return packr.pack(value, encodeOptions);
194
193
  }
195
- packr.lastNamedStructuresLength = sharedLength
194
+ packr.lastNamedStructuresLength = sharedLength;
196
195
  // don't keep large buffers around
197
- if (target.length > 0x40000000) target = null
198
- return returnBuffer
196
+ if (target.length > 0x40000000) target = null;
197
+ return returnBuffer;
199
198
  }
200
199
  }
201
200
  }
202
201
  // don't keep large buffers around, they take too much memory and cause problems (limit at 1GB)
203
- if (target.length > 0x40000000) target = null
202
+ if (target.length > 0x40000000) target = null;
204
203
  if (encodeOptions & RESET_BUFFER_MODE)
205
- position = start
204
+ position = start;
206
205
  }
207
- }
206
+ };
208
207
  const resetStructures = () => {
209
208
  if (serializationsSinceTransitionRebuild < 10)
210
- serializationsSinceTransitionRebuild++
211
- let sharedLength = structures.sharedLength || 0
209
+ serializationsSinceTransitionRebuild++;
210
+ let sharedLength = structures.sharedLength || 0;
212
211
  if (structures.length > sharedLength && !isSequential)
213
- structures.length = sharedLength
212
+ structures.length = sharedLength;
214
213
  if (transitionsCount > 10000) {
215
214
  // force a rebuild occasionally after a lot of transitions so it can get cleaned up
216
- structures.transitions = null
217
- serializationsSinceTransitionRebuild = 0
218
- transitionsCount = 0
215
+ structures.transitions = null;
216
+ serializationsSinceTransitionRebuild = 0;
217
+ transitionsCount = 0;
219
218
  if (recordIdsToRemove.length > 0)
220
- recordIdsToRemove = []
219
+ recordIdsToRemove = [];
221
220
  } else if (recordIdsToRemove.length > 0 && !isSequential) {
222
221
  for (let i = 0, l = recordIdsToRemove.length; i < l; i++) {
223
- recordIdsToRemove[i][RECORD_SYMBOL] = 0
222
+ recordIdsToRemove[i][RECORD_SYMBOL] = 0;
224
223
  }
225
- recordIdsToRemove = []
224
+ recordIdsToRemove = [];
226
225
  }
227
- }
226
+ };
228
227
  const packArray = (value) => {
229
- var length = value.length
228
+ var length = value.length;
230
229
  if (length < 0x10) {
231
- target[position++] = 0x90 | length
230
+ target[position++] = 0x90 | length;
232
231
  } else if (length < 0x10000) {
233
- target[position++] = 0xdc
234
- target[position++] = length >> 8
235
- target[position++] = length & 0xff
232
+ target[position++] = 0xdc;
233
+ target[position++] = length >> 8;
234
+ target[position++] = length & 0xff;
236
235
  } else {
237
- target[position++] = 0xdd
238
- targetView.setUint32(position, length)
239
- position += 4
236
+ target[position++] = 0xdd;
237
+ targetView.setUint32(position, length);
238
+ position += 4;
240
239
  }
241
240
  for (let i = 0; i < length; i++) {
242
- pack(value[i])
241
+ pack(value[i]);
243
242
  }
244
- }
243
+ };
245
244
  const pack = (value) => {
246
245
  if (position > safeEnd)
247
- target = makeRoom(position)
246
+ target = makeRoom(position);
248
247
 
249
- var type = typeof value
250
- var length
248
+ var type = typeof value;
249
+ var length;
251
250
  if (type === 'string') {
252
- let strLength = value.length
251
+ let strLength = value.length;
253
252
  if (bundledStrings && strLength >= 4 && strLength < 0x1000) {
254
253
  if ((bundledStrings.size += strLength) > MAX_BUNDLE_SIZE) {
255
- let extStart
256
- let maxBytes = (bundledStrings[0] ? bundledStrings[0].length * 3 + bundledStrings[1].length : 0) + 10
254
+ let extStart;
255
+ let maxBytes = (bundledStrings[0] ? bundledStrings[0].length * 3 + bundledStrings[1].length : 0) + 10;
257
256
  if (position + maxBytes > safeEnd)
258
- target = makeRoom(position + maxBytes)
259
- let lastBundle
257
+ target = makeRoom(position + maxBytes);
258
+ let lastBundle;
260
259
  if (bundledStrings.position) { // here we use the 0x62 extension to write the last bundle and reserve space for the reference pointer to the next/current bundle
261
- lastBundle = bundledStrings
262
- target[position] = 0xc8 // ext 16
263
- position += 3 // reserve for the writing bundle size
264
- target[position++] = 0x62 // 'b'
265
- extStart = position - start
266
- position += 4 // reserve for writing bundle reference
267
- writeBundles(start, pack, 0) // write the last bundles
268
- targetView.setUint16(extStart + start - 3, position - start - extStart)
260
+ lastBundle = bundledStrings;
261
+ target[position] = 0xc8; // ext 16
262
+ position += 3; // reserve for the writing bundle size
263
+ target[position++] = 0x62; // 'b'
264
+ extStart = position - start;
265
+ position += 4; // reserve for writing bundle reference
266
+ writeBundles(start, pack, 0); // write the last bundles
267
+ targetView.setUint16(extStart + start - 3, position - start - extStart);
269
268
  } else { // here we use the 0x62 extension just to reserve the space for the reference pointer to the bundle (will be updated once the bundle is written)
270
- target[position++] = 0xd6 // fixext 4
271
- target[position++] = 0x62 // 'b'
272
- extStart = position - start
273
- position += 4 // reserve for writing bundle reference
269
+ target[position++] = 0xd6; // fixext 4
270
+ target[position++] = 0x62; // 'b'
271
+ extStart = position - start;
272
+ position += 4; // reserve for writing bundle reference
274
273
  }
275
- bundledStrings = ['', ''] // create new ones
274
+ bundledStrings = ['', '']; // create new ones
276
275
  bundledStrings.previous = lastBundle;
277
- bundledStrings.size = 0
278
- bundledStrings.position = extStart
276
+ bundledStrings.size = 0;
277
+ bundledStrings.position = extStart;
279
278
  }
280
- let twoByte = hasNonLatin.test(value)
281
- bundledStrings[twoByte ? 0 : 1] += value
282
- target[position++] = 0xc1
279
+ let twoByte = hasNonLatin.test(value);
280
+ bundledStrings[twoByte ? 0 : 1] += value;
281
+ target[position++] = 0xc1;
283
282
  pack(twoByte ? -strLength : strLength);
284
- return
283
+ return;
285
284
  }
286
- let headerSize
285
+ let headerSize;
287
286
  // first we estimate the header size, so we can write to the correct location
288
287
  if (strLength < 0x20) {
289
- headerSize = 1
288
+ headerSize = 1;
290
289
  } else if (strLength < 0x100) {
291
- headerSize = 2
290
+ headerSize = 2;
292
291
  } else if (strLength < 0x10000) {
293
- headerSize = 3
292
+ headerSize = 3;
294
293
  } else {
295
- headerSize = 5
294
+ headerSize = 5;
296
295
  }
297
- let maxBytes = strLength * 3
296
+ let maxBytes = strLength * 3;
298
297
  if (position + maxBytes > safeEnd)
299
- target = makeRoom(position + maxBytes)
298
+ target = makeRoom(position + maxBytes);
300
299
 
301
300
  if (strLength < 0x40 || !encodeUtf8) {
302
- let i, c1, c2, strPosition = position + headerSize
301
+ let i, c1, c2, strPosition = position + headerSize;
303
302
  for (i = 0; i < strLength; i++) {
304
- c1 = value.charCodeAt(i)
303
+ c1 = value.charCodeAt(i);
305
304
  if (c1 < 0x80) {
306
- target[strPosition++] = c1
305
+ target[strPosition++] = c1;
307
306
  } else if (c1 < 0x800) {
308
- target[strPosition++] = c1 >> 6 | 0xc0
309
- target[strPosition++] = c1 & 0x3f | 0x80
307
+ target[strPosition++] = c1 >> 6 | 0xc0;
308
+ target[strPosition++] = c1 & 0x3f | 0x80;
310
309
  } else if (
311
310
  (c1 & 0xfc00) === 0xd800 &&
312
311
  ((c2 = value.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
313
312
  ) {
314
- c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff)
315
- i++
316
- target[strPosition++] = c1 >> 18 | 0xf0
317
- target[strPosition++] = c1 >> 12 & 0x3f | 0x80
318
- target[strPosition++] = c1 >> 6 & 0x3f | 0x80
319
- target[strPosition++] = c1 & 0x3f | 0x80
313
+ c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff);
314
+ i++;
315
+ target[strPosition++] = c1 >> 18 | 0xf0;
316
+ target[strPosition++] = c1 >> 12 & 0x3f | 0x80;
317
+ target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
318
+ target[strPosition++] = c1 & 0x3f | 0x80;
320
319
  } else {
321
- target[strPosition++] = c1 >> 12 | 0xe0
322
- target[strPosition++] = c1 >> 6 & 0x3f | 0x80
323
- target[strPosition++] = c1 & 0x3f | 0x80
320
+ target[strPosition++] = c1 >> 12 | 0xe0;
321
+ target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
322
+ target[strPosition++] = c1 & 0x3f | 0x80;
324
323
  }
325
324
  }
326
- length = strPosition - position - headerSize
325
+ length = strPosition - position - headerSize;
327
326
  } else {
328
- length = encodeUtf8(value, position + headerSize)
327
+ length = encodeUtf8(value, position + headerSize);
329
328
  }
330
329
 
331
330
  if (length < 0x20) {
332
- target[position++] = 0xa0 | length
331
+ target[position++] = 0xa0 | length;
333
332
  } else if (length < 0x100) {
334
333
  if (headerSize < 2) {
335
- target.copyWithin(position + 2, position + 1, position + 1 + length)
334
+ target.copyWithin(position + 2, position + 1, position + 1 + length);
336
335
  }
337
- target[position++] = 0xd9
338
- target[position++] = length
336
+ target[position++] = 0xd9;
337
+ target[position++] = length;
339
338
  } else if (length < 0x10000) {
340
339
  if (headerSize < 3) {
341
- target.copyWithin(position + 3, position + 2, position + 2 + length)
340
+ target.copyWithin(position + 3, position + 2, position + 2 + length);
342
341
  }
343
- target[position++] = 0xda
344
- target[position++] = length >> 8
345
- target[position++] = length & 0xff
342
+ target[position++] = 0xda;
343
+ target[position++] = length >> 8;
344
+ target[position++] = length & 0xff;
346
345
  } else {
347
346
  if (headerSize < 5) {
348
- target.copyWithin(position + 5, position + 3, position + 3 + length)
347
+ target.copyWithin(position + 5, position + 3, position + 3 + length);
349
348
  }
350
- target[position++] = 0xdb
351
- targetView.setUint32(position, length)
352
- position += 4
349
+ target[position++] = 0xdb;
350
+ targetView.setUint32(position, length);
351
+ position += 4;
353
352
  }
354
- position += length
353
+ position += length;
355
354
  } else if (type === 'number') {
356
355
  if (value >>> 0 === value) {// positive integer, 32-bit or less
357
356
  // positive uint
358
- if (value < 0x20 || (value < 0x80 && this.useRecords === false) || (value < 0x40 && !this.randomAccessStructure)) {
359
- target[position++] = value
357
+ if (value < 0x20 || (value < 0x80 && this.useRecords === false) || (value < 0x40 && !this._writeStruct)) {
358
+ target[position++] = value;
360
359
  } else if (value < 0x100) {
361
- target[position++] = 0xcc
362
- target[position++] = value
360
+ target[position++] = 0xcc;
361
+ target[position++] = value;
363
362
  } else if (value < 0x10000) {
364
- target[position++] = 0xcd
365
- target[position++] = value >> 8
366
- target[position++] = value & 0xff
363
+ target[position++] = 0xcd;
364
+ target[position++] = value >> 8;
365
+ target[position++] = value & 0xff;
367
366
  } else {
368
- target[position++] = 0xce
369
- targetView.setUint32(position, value)
370
- position += 4
367
+ target[position++] = 0xce;
368
+ targetView.setUint32(position, value);
369
+ position += 4;
371
370
  }
372
371
  } else if (value >> 0 === value) { // negative integer
373
372
  if (value >= -0x20) {
374
- target[position++] = 0x100 + value
373
+ target[position++] = 0x100 + value;
375
374
  } else if (value >= -0x80) {
376
- target[position++] = 0xd0
377
- target[position++] = value + 0x100
375
+ target[position++] = 0xd0;
376
+ target[position++] = value + 0x100;
378
377
  } else if (value >= -0x8000) {
379
- target[position++] = 0xd1
380
- targetView.setInt16(position, value)
381
- position += 2
378
+ target[position++] = 0xd1;
379
+ targetView.setInt16(position, value);
380
+ position += 2;
382
381
  } else {
383
- target[position++] = 0xd2
384
- targetView.setInt32(position, value)
385
- position += 4
382
+ target[position++] = 0xd2;
383
+ targetView.setInt32(position, value);
384
+ position += 4;
386
385
  }
387
386
  } else {
388
- let useFloat32
387
+ let useFloat32;
389
388
  if ((useFloat32 = this.useFloat32) > 0 && value < 0x100000000 && value >= -0x80000000) {
390
- target[position++] = 0xca
391
- targetView.setFloat32(position, value)
392
- let xShifted
389
+ target[position++] = 0xca;
390
+ targetView.setFloat32(position, value);
391
+ let xShifted;
393
392
  if (useFloat32 < 4 ||
394
393
  // this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
395
394
  ((xShifted = value * mult10[((target[position] & 0x7f) << 1) | (target[position + 1] >> 7)]) >> 0) === xShifted) {
396
- position += 4
397
- return
395
+ position += 4;
396
+ return;
398
397
  } else
399
- position-- // move back into position for writing a double
398
+ position--; // move back into position for writing a double
400
399
  }
401
- target[position++] = 0xcb
402
- targetView.setFloat64(position, value)
403
- position += 8
400
+ target[position++] = 0xcb;
401
+ targetView.setFloat64(position, value);
402
+ position += 8;
404
403
  }
405
404
  } else if (type === 'object' || type === 'function') {
406
405
  if (!value)
407
- target[position++] = 0xc0
406
+ target[position++] = 0xc0;
408
407
  else {
409
408
  if (referenceMap) {
410
- let referee = referenceMap.get(value)
409
+ let referee = referenceMap.get(value);
411
410
  if (referee) {
412
411
  if (!referee.id) {
413
- let idsToInsert = referenceMap.idsToInsert || (referenceMap.idsToInsert = [])
414
- referee.id = idsToInsert.push(referee)
412
+ let idsToInsert = referenceMap.idsToInsert || (referenceMap.idsToInsert = []);
413
+ referee.id = idsToInsert.push(referee);
415
414
  }
416
- target[position++] = 0xd6 // fixext 4
417
- target[position++] = 0x70 // "p" for pointer
418
- targetView.setUint32(position, referee.id)
419
- position += 4
420
- return
415
+ target[position++] = 0xd6; // fixext 4
416
+ target[position++] = 0x70; // "p" for pointer
417
+ targetView.setUint32(position, referee.id);
418
+ position += 4;
419
+ return;
421
420
  } else
422
- referenceMap.set(value, { offset: position - start })
421
+ referenceMap.set(value, { offset: position - start });
423
422
  }
424
- let constructor = value.constructor
423
+ let constructor = value.constructor;
425
424
  if (constructor === Object) {
426
- writeObject(value)
425
+ writeObject(value);
427
426
  } else if (constructor === Array) {
428
- packArray(value)
427
+ packArray(value);
429
428
  } else if (constructor === Map) {
430
- if (this.mapAsEmptyObject) target[position++] = 0x80
429
+ if (this.mapAsEmptyObject) target[position++] = 0x80;
431
430
  else {
432
- length = value.size
431
+ length = value.size;
433
432
  if (length < 0x10) {
434
- target[position++] = 0x80 | length
433
+ target[position++] = 0x80 | length;
435
434
  } else if (length < 0x10000) {
436
- target[position++] = 0xde
437
- target[position++] = length >> 8
438
- target[position++] = length & 0xff
435
+ target[position++] = 0xde;
436
+ target[position++] = length >> 8;
437
+ target[position++] = length & 0xff;
439
438
  } else {
440
- target[position++] = 0xdf
441
- targetView.setUint32(position, length)
442
- position += 4
439
+ target[position++] = 0xdf;
440
+ targetView.setUint32(position, length);
441
+ position += 4;
443
442
  }
444
443
  for (let [key, entryValue] of value) {
445
- pack(key)
446
- pack(entryValue)
444
+ pack(key);
445
+ pack(entryValue);
447
446
  }
448
447
  }
449
448
  } else {
450
449
  for (let i = 0, l = extensions.length; i < l; i++) {
451
- let extensionClass = extensionClasses[i]
450
+ let extensionClass = extensionClasses[i];
452
451
  if (value instanceof extensionClass) {
453
- let extension = extensions[i]
452
+ let extension = extensions[i];
454
453
  if (extension.write) {
455
454
  if (extension.type) {
456
- target[position++] = 0xd4 // one byte "tag" extension
457
- target[position++] = extension.type
458
- target[position++] = 0
455
+ target[position++] = 0xd4; // one byte "tag" extension
456
+ target[position++] = extension.type;
457
+ target[position++] = 0;
459
458
  }
460
- let writeResult = extension.write.call(this, value)
459
+ let writeResult = extension.write.call(this, value);
461
460
  if (writeResult === value) { // avoid infinite recursion
462
461
  if (Array.isArray(value)) {
463
- packArray(value)
462
+ packArray(value);
464
463
  } else {
465
- writeObject(value)
464
+ writeObject(value);
466
465
  }
467
466
  } else {
468
- pack(writeResult)
467
+ pack(writeResult);
469
468
  }
470
- return
469
+ return;
471
470
  }
472
- let currentTarget = target
473
- let currentTargetView = targetView
474
- let currentPosition = position
475
- target = null
476
- let result
471
+ let currentTarget = target;
472
+ let currentTargetView = targetView;
473
+ let currentPosition = position;
474
+ target = null;
475
+ let result;
477
476
  try {
478
477
  result = extension.pack.call(this, value, (size) => {
479
478
  // restore target and use it
480
- target = currentTarget
481
- currentTarget = null
482
- position += size
479
+ target = currentTarget;
480
+ currentTarget = null;
481
+ position += size;
483
482
  if (position > safeEnd)
484
- makeRoom(position)
483
+ makeRoom(position);
485
484
  return {
486
485
  target, targetView, position: position - size
487
- }
488
- }, pack)
486
+ };
487
+ }, pack);
489
488
  } finally {
490
489
  // restore current target information (unless already restored)
491
490
  if (currentTarget) {
492
- target = currentTarget
493
- targetView = currentTargetView
494
- position = currentPosition
495
- safeEnd = target.length - 10
491
+ target = currentTarget;
492
+ targetView = currentTargetView;
493
+ position = currentPosition;
494
+ safeEnd = target.length - 10;
496
495
  }
497
496
  }
498
497
  if (result) {
499
498
  if (result.length + position > safeEnd)
500
- makeRoom(result.length + position)
501
- position = writeExtensionData(result, target, position, extension.type)
499
+ makeRoom(result.length + position);
500
+ position = writeExtensionData(result, target, position, extension.type);
502
501
  }
503
- return
502
+ return;
504
503
  }
505
504
  }
506
505
  // check isArray after extensions, because extensions can extend Array
507
506
  if (Array.isArray(value)) {
508
- packArray(value)
507
+ packArray(value);
509
508
  } else {
510
509
  // use this as an alternate mechanism for expressing how to serialize
511
510
  if (value.toJSON) {
512
- const json = value.toJSON()
511
+ const json = value.toJSON();
513
512
  // if for some reason value.toJSON returns itself it'll loop forever
514
513
  if (json !== value)
515
- return pack(json)
514
+ return pack(json);
516
515
  }
517
516
 
518
517
  // if there is a writeFunction, use it, otherwise just encode as undefined
@@ -520,89 +519,89 @@ export class Packr extends Unpackr {
520
519
  return pack(this.writeFunction && this.writeFunction(value));
521
520
 
522
521
  // no extension found, write as plain object
523
- writeObject(value)
522
+ writeObject(value);
524
523
  }
525
524
  }
526
525
  }
527
526
  } else if (type === 'boolean') {
528
- target[position++] = value ? 0xc3 : 0xc2
527
+ target[position++] = value ? 0xc3 : 0xc2;
529
528
  } else if (type === 'bigint') {
530
529
  if (value < 0x8000000000000000 && value >= -0x8000000000000000) {
531
530
  // use a signed int as long as it fits
532
- target[position++] = 0xd3
533
- targetView.setBigInt64(position, value)
531
+ target[position++] = 0xd3;
532
+ targetView.setBigInt64(position, value);
534
533
  } else if (value < 0x10000000000000000 && value > 0) {
535
534
  // if we can fit an unsigned int, use that
536
- target[position++] = 0xcf
537
- targetView.setBigUint64(position, value)
535
+ target[position++] = 0xcf;
536
+ targetView.setBigUint64(position, value);
538
537
  } else {
539
538
  // overflow
540
539
  if (this.largeBigIntToFloat) {
541
- target[position++] = 0xcb
542
- targetView.setFloat64(position, Number(value))
540
+ target[position++] = 0xcb;
541
+ targetView.setFloat64(position, Number(value));
543
542
  } else if (this.largeBigIntToString) {
544
543
  return pack(value.toString());
545
544
  } else if (this.useBigIntExtension || this.moreTypes) {
546
- let empty = value < 0 ? BigInt(-1) : BigInt(0)
545
+ let empty = value < 0 ? BigInt(-1) : BigInt(0);
547
546
 
548
- let array
547
+ let array;
549
548
  if (value >> BigInt(0x10000) === empty) {
550
- let mask = BigInt(0x10000000000000000) - BigInt(1) // literal would overflow
551
- let chunks = []
549
+ let mask = BigInt(0x10000000000000000) - BigInt(1); // literal would overflow
550
+ let chunks = [];
552
551
  while (true) {
553
- chunks.push(value & mask)
554
- if ((value >> BigInt(63)) === empty) break
555
- value >>= BigInt(64)
552
+ chunks.push(value & mask);
553
+ if ((value >> BigInt(63)) === empty) break;
554
+ value >>= BigInt(64);
556
555
  }
557
556
 
558
- array = new Uint8Array(new BigUint64Array(chunks).buffer)
559
- array.reverse()
557
+ array = new Uint8Array(new BigUint64Array(chunks).buffer);
558
+ array.reverse();
560
559
  } else {
561
- let invert = value < 0
562
- let string = (invert ? ~value : value).toString(16)
560
+ let invert = value < 0;
561
+ let string = (invert ? ~value : value).toString(16);
563
562
  if (string.length % 2) {
564
- string = '0' + string
563
+ string = '0' + string;
565
564
  } else if (parseInt(string.charAt(0), 16) >= 8) {
566
- string = '00' + string
565
+ string = '00' + string;
567
566
  }
568
567
 
569
568
  if (hasNodeBuffer) {
570
- array = Buffer.from(string, 'hex')
569
+ array = Buffer.from(string, 'hex');
571
570
  } else {
572
- array = new Uint8Array(string.length / 2)
571
+ array = new Uint8Array(string.length / 2);
573
572
  for (let i = 0; i < array.length; i++) {
574
- array[i] = parseInt(string.slice(i * 2, i * 2 + 2), 16)
573
+ array[i] = parseInt(string.slice(i * 2, i * 2 + 2), 16);
575
574
  }
576
575
  }
577
576
 
578
577
  if (invert) {
579
- for (let i = 0; i < array.length; i++) array[i] = ~array[i]
578
+ for (let i = 0; i < array.length; i++) array[i] = ~array[i];
580
579
  }
581
580
  }
582
581
 
583
582
  if (array.length + position > safeEnd)
584
- makeRoom(array.length + position)
585
- position = writeExtensionData(array, target, position, 0x42)
586
- return
583
+ makeRoom(array.length + position);
584
+ position = writeExtensionData(array, target, position, 0x42);
585
+ return;
587
586
  } else {
588
587
  throw new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format, use' +
589
588
  ' useBigIntExtension, or set largeBigIntToFloat to convert to float-64, or set' +
590
- ' largeBigIntToString to convert to string')
589
+ ' largeBigIntToString to convert to string');
591
590
  }
592
591
  }
593
- position += 8
592
+ position += 8;
594
593
  } else if (type === 'undefined') {
595
594
  if (this.encodeUndefinedAsNil)
596
- target[position++] = 0xc0
595
+ target[position++] = 0xc0;
597
596
  else {
598
- target[position++] = 0xd4 // a number of implementations use fixext1 with type 0, data 0 to denote undefined, so we follow suite
599
- target[position++] = 0
600
- target[position++] = 0
597
+ target[position++] = 0xd4; // a number of implementations use fixext1 with type 0, data 0 to denote undefined, so we follow suite
598
+ target[position++] = 0;
599
+ target[position++] = 0;
601
600
  }
602
601
  } else {
603
- throw new Error('Unknown type: ' + type)
602
+ throw new Error('Unknown type: ' + type);
604
603
  }
605
- }
604
+ };
606
605
 
607
606
  const writePlainObject = (this.variableMapSize || this.coercibleKeyAsNumber || this.skipValues) ? (object) => {
608
607
  // this method is slightly slower, but generates "preferred serialization" (optimally small for smaller objects)
@@ -615,263 +614,264 @@ export class Packr extends Unpackr {
615
614
  keys.push(key);
616
615
  }
617
616
  } else {
618
- keys = Object.keys(object)
617
+ keys = Object.keys(object);
619
618
  }
620
- let length = keys.length
619
+ let length = keys.length;
621
620
  if (length < 0x10) {
622
- target[position++] = 0x80 | length
621
+ target[position++] = 0x80 | length;
623
622
  } else if (length < 0x10000) {
624
- target[position++] = 0xde
625
- target[position++] = length >> 8
626
- target[position++] = length & 0xff
623
+ target[position++] = 0xde;
624
+ target[position++] = length >> 8;
625
+ target[position++] = length & 0xff;
627
626
  } else {
628
- target[position++] = 0xdf
629
- targetView.setUint32(position, length)
630
- position += 4
627
+ target[position++] = 0xdf;
628
+ targetView.setUint32(position, length);
629
+ position += 4;
631
630
  }
632
- let key
631
+ let key;
633
632
  if (this.coercibleKeyAsNumber) {
634
633
  for (let i = 0; i < length; i++) {
635
- key = keys[i]
636
- let num = Number(key)
637
- pack(isNaN(num) ? key : num)
638
- pack(object[key])
634
+ key = keys[i];
635
+ let num = Number(key);
636
+ pack(isNaN(num) ? key : num);
637
+ pack(object[key]);
639
638
  }
640
639
 
641
640
  } else {
642
641
  for (let i = 0; i < length; i++) {
643
- pack(key = keys[i])
644
- pack(object[key])
642
+ pack(key = keys[i]);
643
+ pack(object[key]);
645
644
  }
646
645
  }
647
646
  } :
648
647
  (object) => {
649
- target[position++] = 0xde // always using map 16, so we can preallocate and set the length afterwards
650
- let objectOffset = position - start
651
- position += 2
652
- let size = 0
648
+ target[position++] = 0xde; // always using map 16, so we can preallocate and set the length afterwards
649
+ let objectOffset = position - start;
650
+ position += 2;
651
+ let size = 0;
653
652
  for (let key in object) {
654
653
  if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
655
- pack(key)
656
- pack(object[key])
657
- size++
654
+ pack(key);
655
+ pack(object[key]);
656
+ size++;
658
657
  }
659
658
  }
660
659
  if (size > 0xffff) {
661
660
  throw new Error('Object is too large to serialize with fast 16-bit map size,' +
662
661
  ' use the "variableMapSize" option to serialize this object');
663
662
  }
664
- target[objectOffset++ + start] = size >> 8
665
- target[objectOffset + start] = size & 0xff
666
- }
663
+ target[objectOffset++ + start] = size >> 8;
664
+ target[objectOffset + start] = size & 0xff;
665
+ };
667
666
 
668
667
  const writeRecord = this.useRecords === false ? writePlainObject :
669
668
  (options.progressiveRecords && !useTwoByteRecords) ? // this is about 2% faster for highly stable structures, since it only requires one for-in loop (but much more expensive when new structure needs to be written)
670
669
  (object) => {
671
- let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null))
672
- let objectOffset = position++ - start
673
- let wroteKeys
670
+ let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
671
+ let objectOffset = position++ - start;
672
+ let wroteKeys;
674
673
  for (let key in object) {
675
674
  if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
676
- nextTransition = transition[key]
675
+ nextTransition = transition[key];
677
676
  if (nextTransition)
678
- transition = nextTransition
677
+ transition = nextTransition;
679
678
  else {
680
679
  // record doesn't exist, create full new record and insert it
681
- let keys = Object.keys(object)
682
- let lastTransition = transition
683
- transition = structures.transitions
684
- let newTransitions = 0
680
+ let keys = Object.keys(object);
681
+ let lastTransition = transition;
682
+ transition = structures.transitions;
683
+ let newTransitions = 0;
685
684
  for (let i = 0, l = keys.length; i < l; i++) {
686
- let key = keys[i]
687
- nextTransition = transition[key]
685
+ let key = keys[i];
686
+ nextTransition = transition[key];
688
687
  if (!nextTransition) {
689
- nextTransition = transition[key] = Object.create(null)
690
- newTransitions++
688
+ nextTransition = transition[key] = Object.create(null);
689
+ newTransitions++;
691
690
  }
692
- transition = nextTransition
691
+ transition = nextTransition;
693
692
  }
694
693
  if (objectOffset + start + 1 == position) {
695
694
  // first key, so we don't need to insert, we can just write record directly
696
- position--
697
- newRecord(transition, keys, newTransitions)
695
+ position--;
696
+ newRecord(transition, keys, newTransitions);
698
697
  } else // otherwise we need to insert the record, moving existing data after the record
699
- insertNewRecord(transition, keys, objectOffset, newTransitions)
700
- wroteKeys = true
701
- transition = lastTransition[key]
698
+ insertNewRecord(transition, keys, objectOffset, newTransitions);
699
+ wroteKeys = true;
700
+ transition = lastTransition[key];
702
701
  }
703
- pack(object[key])
702
+ pack(object[key]);
704
703
  }
705
704
  }
706
705
  if (!wroteKeys) {
707
- let recordId = transition[RECORD_SYMBOL]
706
+ let recordId = transition[RECORD_SYMBOL];
708
707
  if (recordId)
709
- target[objectOffset + start] = recordId
708
+ target[objectOffset + start] = recordId;
710
709
  else
711
- insertNewRecord(transition, Object.keys(object), objectOffset, 0)
710
+ insertNewRecord(transition, Object.keys(object), objectOffset, 0);
712
711
  }
713
712
  } :
714
713
  (object) => {
715
- let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null))
716
- let newTransitions = 0
714
+ let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
715
+ let newTransitions = 0;
717
716
  for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
718
- nextTransition = transition[key]
717
+ nextTransition = transition[key];
719
718
  if (!nextTransition) {
720
- nextTransition = transition[key] = Object.create(null)
721
- newTransitions++
719
+ nextTransition = transition[key] = Object.create(null);
720
+ newTransitions++;
722
721
  }
723
- transition = nextTransition
722
+ transition = nextTransition;
724
723
  }
725
- let recordId = transition[RECORD_SYMBOL]
724
+ let recordId = transition[RECORD_SYMBOL];
726
725
  if (recordId) {
727
726
  if (recordId >= 0x60 && useTwoByteRecords) {
728
- target[position++] = ((recordId -= 0x60) & 0x1f) + 0x60
729
- target[position++] = recordId >> 5
727
+ target[position++] = ((recordId -= 0x60) & 0x1f) + 0x60;
728
+ target[position++] = recordId >> 5;
730
729
  } else
731
- target[position++] = recordId
730
+ target[position++] = recordId;
732
731
  } else {
733
- newRecord(transition, transition.__keys__ || Object.keys(object), newTransitions)
732
+ newRecord(transition, transition.__keys__ || Object.keys(object), newTransitions);
734
733
  }
735
734
  // now write the values
736
735
  for (let key in object)
737
736
  if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
738
- pack(object[key])
737
+ pack(object[key]);
739
738
  }
740
- }
739
+ };
741
740
 
742
741
  // create reference to useRecords if useRecords is a function
743
742
  const checkUseRecords = typeof this.useRecords == 'function' && this.useRecords;
744
743
 
745
744
  const writeObject = checkUseRecords ? (object) => {
746
- checkUseRecords(object) ? writeRecord(object) : writePlainObject(object)
747
- } : writeRecord
745
+ checkUseRecords(object) ? writeRecord(object) : writePlainObject(object);
746
+ } : writeRecord;
747
+
748
+ const writeStruct = (object) => {
749
+ let newPosition = packr._writeStruct(object, target, start, position, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
750
+ if (notifySharedUpdate)
751
+ return hasSharedUpdate = true;
752
+ position = newPosition;
753
+ let startTarget = target;
754
+ pack(value);
755
+ resetStructures();
756
+ if (startTarget !== target) {
757
+ return { position, targetView, target }; // indicate the buffer was re-allocated
758
+ }
759
+ return position;
760
+ });
761
+ if (newPosition === 0) // bail and go to a msgpack object
762
+ return writeObject(object);
763
+ position = newPosition;
764
+ };
748
765
 
749
766
  const makeRoom = (end) => {
750
- let newSize
767
+ let newSize;
751
768
  if (end > 0x1000000) {
752
769
  // special handling for really large buffers
753
770
  if ((end - start) > MAX_BUFFER_SIZE)
754
- throw new Error('Packed buffer would be larger than maximum buffer size')
771
+ throw new Error('Packed buffer would be larger than maximum buffer size');
755
772
  newSize = Math.min(MAX_BUFFER_SIZE,
756
- Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000)
773
+ Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000);
757
774
  } else // faster handling for smaller buffers
758
- newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12
759
- let newBuffer = new ByteArrayAllocate(newSize)
760
- targetView = newBuffer.dataView || (newBuffer.dataView = new DataView(newBuffer.buffer, 0, newSize))
761
- end = Math.min(end, target.length)
775
+ newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12;
776
+ let newBuffer = new ByteArrayAllocate(newSize);
777
+ targetView = newBuffer.dataView || (newBuffer.dataView = new DataView(newBuffer.buffer, 0, newSize));
778
+ end = Math.min(end, target.length);
762
779
  if (target.copy)
763
- target.copy(newBuffer, 0, start, end)
780
+ target.copy(newBuffer, 0, start, end);
764
781
  else
765
- newBuffer.set(target.slice(start, end))
766
- position -= start
767
- start = 0
768
- safeEnd = newBuffer.length - 10
769
- return target = newBuffer
770
- }
782
+ newBuffer.set(target.slice(start, end));
783
+ position -= start;
784
+ start = 0;
785
+ safeEnd = newBuffer.length - 10;
786
+ return target = newBuffer;
787
+ };
771
788
  const newRecord = (transition, keys, newTransitions) => {
772
- let recordId = structures.nextId
789
+ let recordId = structures.nextId;
773
790
  if (!recordId)
774
- recordId = 0x40
791
+ recordId = 0x40;
775
792
  if (recordId < sharedLimitId && this.shouldShareStructure && !this.shouldShareStructure(keys)) {
776
- recordId = structures.nextOwnId
793
+ recordId = structures.nextOwnId;
777
794
  if (!(recordId < maxStructureId))
778
- recordId = sharedLimitId
779
- structures.nextOwnId = recordId + 1
795
+ recordId = sharedLimitId;
796
+ structures.nextOwnId = recordId + 1;
780
797
  } else {
781
798
  if (recordId >= maxStructureId)// cycle back around
782
- recordId = sharedLimitId
783
- structures.nextId = recordId + 1
799
+ recordId = sharedLimitId;
800
+ structures.nextId = recordId + 1;
784
801
  }
785
- let highByte = keys.highByte = recordId >= 0x60 && useTwoByteRecords ? (recordId - 0x60) >> 5 : -1
786
- transition[RECORD_SYMBOL] = recordId
787
- transition.__keys__ = keys
788
- structures[recordId - 0x40] = keys
802
+ let highByte = keys.highByte = recordId >= 0x60 && useTwoByteRecords ? (recordId - 0x60) >> 5 : -1;
803
+ transition[RECORD_SYMBOL] = recordId;
804
+ transition.__keys__ = keys;
805
+ structures[recordId - 0x40] = keys;
789
806
 
790
807
  if (recordId < sharedLimitId) {
791
- keys.isShared = true
792
- structures.sharedLength = recordId - 0x3f
793
- hasSharedUpdate = true
808
+ keys.isShared = true;
809
+ structures.sharedLength = recordId - 0x3f;
810
+ hasSharedUpdate = true;
794
811
  if (highByte >= 0) {
795
- target[position++] = (recordId & 0x1f) + 0x60
796
- target[position++] = highByte
812
+ target[position++] = (recordId & 0x1f) + 0x60;
813
+ target[position++] = highByte;
797
814
  } else {
798
- target[position++] = recordId
815
+ target[position++] = recordId;
799
816
  }
800
817
  } else {
801
818
  if (highByte >= 0) {
802
- target[position++] = 0xd5 // fixext 2
803
- target[position++] = 0x72 // "r" record defintion extension type
804
- target[position++] = (recordId & 0x1f) + 0x60
805
- target[position++] = highByte
819
+ target[position++] = 0xd5; // fixext 2
820
+ target[position++] = 0x72; // "r" record defintion extension type
821
+ target[position++] = (recordId & 0x1f) + 0x60;
822
+ target[position++] = highByte;
806
823
  } else {
807
- target[position++] = 0xd4 // fixext 1
808
- target[position++] = 0x72 // "r" record defintion extension type
809
- target[position++] = recordId
824
+ target[position++] = 0xd4; // fixext 1
825
+ target[position++] = 0x72; // "r" record defintion extension type
826
+ target[position++] = recordId;
810
827
  }
811
828
 
812
829
  if (newTransitions)
813
- transitionsCount += serializationsSinceTransitionRebuild * newTransitions
830
+ transitionsCount += serializationsSinceTransitionRebuild * newTransitions;
814
831
  // record the removal of the id, we can maintain our shared structure
815
832
  if (recordIdsToRemove.length >= maxOwnStructures)
816
- recordIdsToRemove.shift()[RECORD_SYMBOL] = 0 // we are cycling back through, and have to remove old ones
817
- recordIdsToRemove.push(transition)
818
- pack(keys)
833
+ recordIdsToRemove.shift()[RECORD_SYMBOL] = 0; // we are cycling back through, and have to remove old ones
834
+ recordIdsToRemove.push(transition);
835
+ pack(keys);
819
836
  }
820
- }
837
+ };
821
838
  const insertNewRecord = (transition, keys, insertionOffset, newTransitions) => {
822
- let mainTarget = target
823
- let mainPosition = position
824
- let mainSafeEnd = safeEnd
825
- let mainStart = start
826
- target = keysTarget
827
- position = 0
828
- start = 0
839
+ let mainTarget = target;
840
+ let mainPosition = position;
841
+ let mainSafeEnd = safeEnd;
842
+ let mainStart = start;
843
+ target = keysTarget;
844
+ position = 0;
845
+ start = 0;
829
846
  if (!target)
830
- keysTarget = target = new ByteArrayAllocate(8192)
831
- safeEnd = target.length - 10
832
- newRecord(transition, keys, newTransitions)
833
- keysTarget = target
834
- let keysPosition = position
835
- target = mainTarget
836
- position = mainPosition
837
- safeEnd = mainSafeEnd
838
- start = mainStart
847
+ keysTarget = target = new ByteArrayAllocate(8192);
848
+ safeEnd = target.length - 10;
849
+ newRecord(transition, keys, newTransitions);
850
+ keysTarget = target;
851
+ let keysPosition = position;
852
+ target = mainTarget;
853
+ position = mainPosition;
854
+ safeEnd = mainSafeEnd;
855
+ start = mainStart;
839
856
  if (keysPosition > 1) {
840
- let newEnd = position + keysPosition - 1
857
+ let newEnd = position + keysPosition - 1;
841
858
  if (newEnd > safeEnd)
842
- makeRoom(newEnd)
843
- let insertionPosition = insertionOffset + start
844
- target.copyWithin(insertionPosition + keysPosition, insertionPosition + 1, position)
845
- target.set(keysTarget.slice(0, keysPosition), insertionPosition)
846
- position = newEnd
859
+ makeRoom(newEnd);
860
+ let insertionPosition = insertionOffset + start;
861
+ target.copyWithin(insertionPosition + keysPosition, insertionPosition + 1, position);
862
+ target.set(keysTarget.slice(0, keysPosition), insertionPosition);
863
+ position = newEnd;
847
864
  } else {
848
- target[insertionOffset + start] = keysTarget[0]
865
+ target[insertionOffset + start] = keysTarget[0];
849
866
  }
850
- }
851
- const writeStruct = (object) => {
852
- let newPosition = writeStructSlots(object, target, start, position, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
853
- if (notifySharedUpdate)
854
- return hasSharedUpdate = true;
855
- position = newPosition;
856
- let startTarget = target;
857
- pack(value);
858
- resetStructures();
859
- if (startTarget !== target) {
860
- return { position, targetView, target }; // indicate the buffer was re-allocated
861
- }
862
- return position;
863
- }, this);
864
- if (newPosition === 0) // bail and go to a msgpack object
865
- return writeObject(object);
866
- position = newPosition;
867
- }
867
+ };
868
868
  }
869
869
  useBuffer(buffer) {
870
870
  // this means we are finished using our own buffer and we can write over it safely
871
- target = buffer
872
- target.dataView || (target.dataView = new DataView(target.buffer, target.byteOffset, target.byteLength))
871
+ target = buffer;
872
+ target.dataView || (target.dataView = new DataView(target.buffer, target.byteOffset, target.byteLength));
873
873
  targetView = target.dataView;
874
- position = 0
874
+ position = 0;
875
875
  }
876
876
  set position (value) {
877
877
  position = value;
@@ -881,261 +881,262 @@ export class Packr extends Unpackr {
881
881
  }
882
882
  clearSharedData() {
883
883
  if (this.structures)
884
- this.structures = []
884
+ this.structures = [];
885
885
  if (this.typedStructs)
886
- this.typedStructs = []
886
+ this.typedStructs = [];
887
887
  }
888
888
  }
889
889
 
890
- extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, DataView, C1Type ]
890
+ extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, DataView, C1Type ];
891
891
  extensions = [{
892
892
  pack(date, allocateForWrite, pack) {
893
- let seconds = date.getTime() / 1000
893
+ let seconds = date.getTime() / 1000;
894
894
  if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
895
895
  // Timestamp 32
896
- let { target, targetView, position} = allocateForWrite(6)
897
- target[position++] = 0xd6
898
- target[position++] = 0xff
899
- targetView.setUint32(position, seconds)
896
+ let { target, targetView, position} = allocateForWrite(6);
897
+ target[position++] = 0xd6;
898
+ target[position++] = 0xff;
899
+ targetView.setUint32(position, seconds);
900
900
  } else if (seconds > 0 && seconds < 0x100000000) {
901
901
  // Timestamp 64
902
- let { target, targetView, position} = allocateForWrite(10)
903
- target[position++] = 0xd7
904
- target[position++] = 0xff
905
- targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0))
906
- targetView.setUint32(position + 4, seconds)
902
+ let { target, targetView, position} = allocateForWrite(10);
903
+ target[position++] = 0xd7;
904
+ target[position++] = 0xff;
905
+ targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0));
906
+ targetView.setUint32(position + 4, seconds);
907
907
  } else if (isNaN(seconds)) {
908
908
  if (this.onInvalidDate) {
909
- allocateForWrite(0)
910
- return pack(this.onInvalidDate())
909
+ allocateForWrite(0);
910
+ return pack(this.onInvalidDate());
911
911
  }
912
912
  // Intentionally invalid timestamp
913
- let { target, targetView, position} = allocateForWrite(3)
914
- target[position++] = 0xd4
915
- target[position++] = 0xff
916
- target[position++] = 0xff
913
+ let { target, targetView, position} = allocateForWrite(3);
914
+ target[position++] = 0xd4;
915
+ target[position++] = 0xff;
916
+ target[position++] = 0xff;
917
917
  } else {
918
918
  // Timestamp 96
919
- let { target, targetView, position} = allocateForWrite(15)
920
- target[position++] = 0xc7
921
- target[position++] = 12
922
- target[position++] = 0xff
923
- targetView.setUint32(position, date.getMilliseconds() * 1000000)
924
- targetView.setBigInt64(position + 4, BigInt(Math.floor(seconds)))
919
+ let { target, targetView, position} = allocateForWrite(15);
920
+ target[position++] = 0xc7;
921
+ target[position++] = 12;
922
+ target[position++] = 0xff;
923
+ targetView.setUint32(position, date.getMilliseconds() * 1000000);
924
+ targetView.setBigInt64(position + 4, BigInt(Math.floor(seconds)));
925
925
  }
926
926
  }
927
927
  }, {
928
928
  pack(set, allocateForWrite, pack) {
929
929
  if (this.setAsEmptyObject) {
930
930
  allocateForWrite(0);
931
- return pack({})
931
+ return pack({});
932
932
  }
933
- let array = Array.from(set)
934
- let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0)
933
+ let array = Array.from(set);
934
+ let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0);
935
935
  if (this.moreTypes) {
936
- target[position++] = 0xd4
937
- target[position++] = 0x73 // 's' for Set
938
- target[position++] = 0
936
+ target[position++] = 0xd4;
937
+ target[position++] = 0x73; // 's' for Set
938
+ target[position++] = 0;
939
939
  }
940
- pack(array)
940
+ pack(array);
941
941
  }
942
942
  }, {
943
943
  pack(error, allocateForWrite, pack) {
944
- let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0)
944
+ let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0);
945
945
  if (this.moreTypes) {
946
- target[position++] = 0xd4
947
- target[position++] = 0x65 // 'e' for error
948
- target[position++] = 0
946
+ target[position++] = 0xd4;
947
+ target[position++] = 0x65; // 'e' for error
948
+ target[position++] = 0;
949
949
  }
950
- pack([ error.name, error.message, error.cause ])
950
+ pack([ error.name, error.message, error.cause ]);
951
951
  }
952
952
  }, {
953
953
  pack(regex, allocateForWrite, pack) {
954
- let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0)
954
+ let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0);
955
955
  if (this.moreTypes) {
956
- target[position++] = 0xd4
957
- target[position++] = 0x78 // 'x' for regeXp
958
- target[position++] = 0
956
+ target[position++] = 0xd4;
957
+ target[position++] = 0x78; // 'x' for regeXp
958
+ target[position++] = 0;
959
959
  }
960
- pack([ regex.source, regex.flags ])
960
+ pack([ regex.source, regex.flags ]);
961
961
  }
962
962
  }, {
963
963
  pack(arrayBuffer, allocateForWrite) {
964
964
  if (this.moreTypes)
965
- writeExtBuffer(arrayBuffer, 0x10, allocateForWrite)
965
+ writeExtBuffer(arrayBuffer, 0x10, allocateForWrite);
966
966
  else
967
- writeBuffer(hasNodeBuffer ? Buffer.from(arrayBuffer) : new Uint8Array(arrayBuffer), allocateForWrite)
967
+ writeBuffer(hasNodeBuffer ? Buffer.from(arrayBuffer) : new Uint8Array(arrayBuffer), allocateForWrite);
968
968
  }
969
969
  }, {
970
970
  pack(typedArray, allocateForWrite) {
971
- let constructor = typedArray.constructor
971
+ let constructor = typedArray.constructor;
972
972
  if (constructor !== ByteArray && this.moreTypes)
973
- writeExtBuffer(typedArray, typedArrays.indexOf(constructor.name), allocateForWrite)
973
+ writeExtBuffer(typedArray, typedArrays.indexOf(constructor.name), allocateForWrite);
974
974
  else
975
- writeBuffer(typedArray, allocateForWrite)
975
+ writeBuffer(typedArray, allocateForWrite);
976
976
  }
977
977
  }, {
978
978
  pack(arrayBuffer, allocateForWrite) {
979
979
  if (this.moreTypes)
980
- writeExtBuffer(arrayBuffer, 0x11, allocateForWrite)
980
+ writeExtBuffer(arrayBuffer, 0x11, allocateForWrite);
981
981
  else
982
- writeBuffer(hasNodeBuffer ? Buffer.from(arrayBuffer) : new Uint8Array(arrayBuffer), allocateForWrite)
982
+ writeBuffer(hasNodeBuffer ? Buffer.from(arrayBuffer) : new Uint8Array(arrayBuffer), allocateForWrite);
983
983
  }
984
984
  }, {
985
985
  pack(c1, allocateForWrite) { // specific 0xC1 object
986
- let { target, position} = allocateForWrite(1)
987
- target[position] = 0xc1
986
+ let { target, position} = allocateForWrite(1);
987
+ target[position] = 0xc1;
988
988
  }
989
- }]
989
+ }];
990
990
 
991
991
  function writeExtBuffer(typedArray, type, allocateForWrite, encode) {
992
- let length = typedArray.byteLength
992
+ let length = typedArray.byteLength;
993
993
  if (length + 1 < 0x100) {
994
- var { target, position } = allocateForWrite(4 + length)
995
- target[position++] = 0xc7
996
- target[position++] = length + 1
994
+ var { target, position } = allocateForWrite(4 + length);
995
+ target[position++] = 0xc7;
996
+ target[position++] = length + 1;
997
997
  } else if (length + 1 < 0x10000) {
998
- var { target, position } = allocateForWrite(5 + length)
999
- target[position++] = 0xc8
1000
- target[position++] = (length + 1) >> 8
1001
- target[position++] = (length + 1) & 0xff
998
+ var { target, position } = allocateForWrite(5 + length);
999
+ target[position++] = 0xc8;
1000
+ target[position++] = (length + 1) >> 8;
1001
+ target[position++] = (length + 1) & 0xff;
1002
1002
  } else {
1003
- var { target, position, targetView } = allocateForWrite(7 + length)
1004
- target[position++] = 0xc9
1005
- targetView.setUint32(position, length + 1) // plus one for the type byte
1006
- position += 4
1003
+ var { target, position, targetView } = allocateForWrite(7 + length);
1004
+ target[position++] = 0xc9;
1005
+ targetView.setUint32(position, length + 1); // plus one for the type byte
1006
+ position += 4;
1007
1007
  }
1008
- target[position++] = 0x74 // "t" for typed array
1009
- target[position++] = type
1010
- if (!typedArray.buffer) typedArray = new Uint8Array(typedArray)
1011
- target.set(new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength), position)
1008
+ target[position++] = 0x74; // "t" for typed array
1009
+ target[position++] = type;
1010
+ if (!typedArray.buffer) typedArray = new Uint8Array(typedArray);
1011
+ target.set(new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength), position);
1012
1012
  }
1013
1013
  function writeBuffer(buffer, allocateForWrite) {
1014
- let length = buffer.byteLength
1015
- var target, position
1014
+ let length = buffer.byteLength;
1015
+ var target, position;
1016
1016
  if (length < 0x100) {
1017
- var { target, position } = allocateForWrite(length + 2)
1018
- target[position++] = 0xc4
1019
- target[position++] = length
1017
+ var { target, position } = allocateForWrite(length + 2);
1018
+ target[position++] = 0xc4;
1019
+ target[position++] = length;
1020
1020
  } else if (length < 0x10000) {
1021
- var { target, position } = allocateForWrite(length + 3)
1022
- target[position++] = 0xc5
1023
- target[position++] = length >> 8
1024
- target[position++] = length & 0xff
1021
+ var { target, position } = allocateForWrite(length + 3);
1022
+ target[position++] = 0xc5;
1023
+ target[position++] = length >> 8;
1024
+ target[position++] = length & 0xff;
1025
1025
  } else {
1026
- var { target, position, targetView } = allocateForWrite(length + 5)
1027
- target[position++] = 0xc6
1028
- targetView.setUint32(position, length)
1029
- position += 4
1026
+ var { target, position, targetView } = allocateForWrite(length + 5);
1027
+ target[position++] = 0xc6;
1028
+ targetView.setUint32(position, length);
1029
+ position += 4;
1030
1030
  }
1031
- target.set(buffer, position)
1031
+ target.set(buffer, position);
1032
1032
  }
1033
1033
 
1034
1034
  function writeExtensionData(result, target, position, type) {
1035
- let length = result.length
1035
+ let length = result.length;
1036
1036
  switch (length) {
1037
1037
  case 1:
1038
- target[position++] = 0xd4
1039
- break
1038
+ target[position++] = 0xd4;
1039
+ break;
1040
1040
  case 2:
1041
- target[position++] = 0xd5
1042
- break
1041
+ target[position++] = 0xd5;
1042
+ break;
1043
1043
  case 4:
1044
- target[position++] = 0xd6
1045
- break
1044
+ target[position++] = 0xd6;
1045
+ break;
1046
1046
  case 8:
1047
- target[position++] = 0xd7
1048
- break
1047
+ target[position++] = 0xd7;
1048
+ break;
1049
1049
  case 16:
1050
- target[position++] = 0xd8
1051
- break
1050
+ target[position++] = 0xd8;
1051
+ break;
1052
1052
  default:
1053
1053
  if (length < 0x100) {
1054
- target[position++] = 0xc7
1055
- target[position++] = length
1054
+ target[position++] = 0xc7;
1055
+ target[position++] = length;
1056
1056
  } else if (length < 0x10000) {
1057
- target[position++] = 0xc8
1058
- target[position++] = length >> 8
1059
- target[position++] = length & 0xff
1057
+ target[position++] = 0xc8;
1058
+ target[position++] = length >> 8;
1059
+ target[position++] = length & 0xff;
1060
1060
  } else {
1061
- target[position++] = 0xc9
1062
- target[position++] = length >> 24
1063
- target[position++] = (length >> 16) & 0xff
1064
- target[position++] = (length >> 8) & 0xff
1065
- target[position++] = length & 0xff
1061
+ target[position++] = 0xc9;
1062
+ target[position++] = length >> 24;
1063
+ target[position++] = (length >> 16) & 0xff;
1064
+ target[position++] = (length >> 8) & 0xff;
1065
+ target[position++] = length & 0xff;
1066
1066
  }
1067
1067
  }
1068
- target[position++] = type
1069
- target.set(result, position)
1070
- position += length
1071
- return position
1068
+ target[position++] = type;
1069
+ target.set(result, position);
1070
+ position += length;
1071
+ return position;
1072
1072
  }
1073
1073
 
1074
1074
  function insertIds(serialized, idsToInsert) {
1075
1075
  // insert the ids that need to be referenced for structured clones
1076
- let nextId
1077
- let distanceToMove = idsToInsert.length * 6
1078
- let lastEnd = serialized.length - distanceToMove
1076
+ let nextId;
1077
+ let distanceToMove = idsToInsert.length * 6;
1078
+ let lastEnd = serialized.length - distanceToMove;
1079
1079
  while (nextId = idsToInsert.pop()) {
1080
- let offset = nextId.offset
1081
- let id = nextId.id
1082
- serialized.copyWithin(offset + distanceToMove, offset, lastEnd)
1083
- distanceToMove -= 6
1084
- let position = offset + distanceToMove
1085
- serialized[position++] = 0xd6
1086
- serialized[position++] = 0x69 // 'i'
1087
- serialized[position++] = id >> 24
1088
- serialized[position++] = (id >> 16) & 0xff
1089
- serialized[position++] = (id >> 8) & 0xff
1090
- serialized[position++] = id & 0xff
1091
- lastEnd = offset
1080
+ let offset = nextId.offset;
1081
+ let id = nextId.id;
1082
+ serialized.copyWithin(offset + distanceToMove, offset, lastEnd);
1083
+ distanceToMove -= 6;
1084
+ let position = offset + distanceToMove;
1085
+ serialized[position++] = 0xd6;
1086
+ serialized[position++] = 0x69; // 'i'
1087
+ serialized[position++] = id >> 24;
1088
+ serialized[position++] = (id >> 16) & 0xff;
1089
+ serialized[position++] = (id >> 8) & 0xff;
1090
+ serialized[position++] = id & 0xff;
1091
+ lastEnd = offset;
1092
1092
  }
1093
- return serialized
1093
+ return serialized;
1094
1094
  }
1095
1095
 
1096
1096
  function writeBundles(start, pack, incrementPosition) {
1097
1097
  if (bundledStrings.length > 0) {
1098
- targetView.setUint32(bundledStrings.position + start, position + incrementPosition - bundledStrings.position - start)
1098
+ targetView.setUint32(bundledStrings.position + start, position + incrementPosition - bundledStrings.position - start);
1099
1099
  bundledStrings.stringsPosition = position - start;
1100
- let writeStrings = bundledStrings
1101
- bundledStrings = null
1102
- pack(writeStrings[0])
1103
- pack(writeStrings[1])
1100
+ let writeStrings = bundledStrings;
1101
+ bundledStrings = null;
1102
+ pack(writeStrings[0]);
1103
+ pack(writeStrings[1]);
1104
1104
  }
1105
1105
  }
1106
1106
 
1107
1107
  export function addExtension(extension) {
1108
1108
  if (extension.Class) {
1109
1109
  if (!extension.pack && !extension.write)
1110
- throw new Error('Extension has no pack or write function')
1110
+ throw new Error('Extension has no pack or write function');
1111
1111
  if (extension.pack && !extension.type)
1112
- throw new Error('Extension has no type (numeric code to identify the extension)')
1113
- extensionClasses.unshift(extension.Class)
1114
- extensions.unshift(extension)
1112
+ throw new Error('Extension has no type (numeric code to identify the extension)');
1113
+ extensionClasses.unshift(extension.Class);
1114
+ extensions.unshift(extension);
1115
1115
  }
1116
- unpackAddExtension(extension)
1116
+ unpackAddExtension(extension);
1117
1117
  }
1118
1118
  function prepareStructures(structures, packr) {
1119
1119
  structures.isCompatible = (existingStructures) => {
1120
- let compatible = !existingStructures || ((packr.lastNamedStructuresLength || 0) === existingStructures.length)
1120
+ let compatible = !existingStructures || ((packr.lastNamedStructuresLength || 0) === existingStructures.length);
1121
1121
  if (!compatible) // we want to merge these existing structures immediately since we already have it and we are in the right transaction
1122
1122
  packr._mergeStructures(existingStructures);
1123
1123
  return compatible;
1124
- }
1125
- return structures
1126
- }
1127
- export function setWriteStructSlots(writeSlots, makeStructures) {
1128
- writeStructSlots = writeSlots;
1129
- prepareStructures = makeStructures;
1124
+ };
1125
+ return structures;
1130
1126
  }
1131
1127
 
1132
- let defaultPackr = new Packr({ useRecords: false })
1133
- export const pack = defaultPackr.pack
1134
- export const encode = defaultPackr.pack
1135
- export const Encoder = Packr
1136
- export { FLOAT32_OPTIONS } from './unpack.js'
1137
- import { FLOAT32_OPTIONS } from './unpack.js'
1138
- export const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS
1139
- export const REUSE_BUFFER_MODE = 512
1140
- export const RESET_BUFFER_MODE = 1024
1141
- export const RESERVE_START_SPACE = 2048
1128
+ // Marker for downstream libraries (e.g. structon) to detect that this Packr
1129
+ // supports per-instance struct-encoding hooks (this._writeStruct,
1130
+ // this._prepareStructures). See `pack` for the dispatch.
1131
+ Packr.SUPPORTS_STRUCT_HOOKS = true;
1132
+
1133
+ let defaultPackr = new Packr({ useRecords: false });
1134
+ export const pack = defaultPackr.pack;
1135
+ export const encode = defaultPackr.pack;
1136
+ export const Encoder = Packr;
1137
+ export { FLOAT32_OPTIONS } from './unpack.js';
1138
+ import { FLOAT32_OPTIONS } from './unpack.js';
1139
+ export const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
1140
+ export const REUSE_BUFFER_MODE = 512;
1141
+ export const RESET_BUFFER_MODE = 1024;
1142
+ export const RESERVE_START_SPACE = 2048;