msgpackr 1.5.0 → 1.5.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/README.md CHANGED
@@ -168,6 +168,7 @@ The following options properties can be provided to the Packr or Unpackr constru
168
168
  * `largeBigIntToFloat` - If a bigint needs to be encoded that is larger than will fit in 64-bit integers, it will be encoded as a float-64 (otherwise will throw a RangeError).
169
169
  * `encodeUndefinedAsNil` - Encodes a value of `undefined` as a MessagePack `nil`, the same as a `null`.
170
170
  * `int64AsNumber` - This will decode uint64 and int64 numbers as standard JS numbers rather than as bigint numbers.
171
+ * `onInvalidDate` - This can be provided as function that will be called when an invalid date is provided. The function can throw an error, or return a value that will be encoded in place of the invalid date. If not provided, an invalid date will be encoded as an invalid timestamp (which decodes with msgpackr back to an invalid date).
171
172
 
172
173
  ### 32-bit Float Options
173
174
  By default all non-integer numbers are serialized as 64-bit float (double). This is fast, and ensures maximum precision. However, often real-world data doesn't not need 64-bits of precision, and using 32-bit encoding can be much more space efficient. There are several options that provide more efficient encodings. Using the decimal rounding options for encoding and decoding provides lossless storage of common decimal representations like 7.99, in more efficient 32-bit format (rather than 64-bit). The `useFloat32` property has several possible options, available from the module as constants:
package/dist/index.js CHANGED
@@ -870,7 +870,7 @@
870
870
  ((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]) / 1000000 +
871
871
  (((data[4] & 0x80) ? -0x1000000000000 : 0) + data[6] * 0x10000000000 + data[7] * 0x100000000 + data[8] * 0x1000000 + (data[9] << 16) + (data[10] << 8) + data[11]) * 1000)
872
872
  else
873
- throw new Error('Invalid timestamp length')
873
+ return new Date('invalid')
874
874
  }; // notepack defines extension 0 to mean undefined, so use that as the default here
875
875
  // registration of bulk record definition?
876
876
  // currentExtensions[0x52] = () =>
@@ -1555,7 +1555,7 @@
1555
1555
 
1556
1556
  extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, C1Type ];
1557
1557
  extensions = [{
1558
- pack(date, allocateForWrite) {
1558
+ pack(date, allocateForWrite, pack) {
1559
1559
  let seconds = date.getTime() / 1000;
1560
1560
  if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
1561
1561
  // Timestamp 32
@@ -1570,6 +1570,14 @@
1570
1570
  target[position++] = 0xff;
1571
1571
  targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0));
1572
1572
  targetView.setUint32(position + 4, seconds);
1573
+ } else if (isNaN(seconds)) {
1574
+ if (this.onInvalidDate)
1575
+ return pack(this.onInvalidDate())
1576
+ // Intentionally invalid timestamp
1577
+ let { target, targetView, position} = allocateForWrite(3);
1578
+ target[position++] = 0xd4;
1579
+ target[position++] = 0xff;
1580
+ target[position++] = 0xff;
1573
1581
  } else {
1574
1582
  // Timestamp 96
1575
1583
  let { target, targetView, position} = allocateForWrite(15);
package/dist/index.min.js CHANGED
@@ -44,9 +44,7 @@ E.set(a,d);let f=e();// read the next value as the target object to id
44
44
  return d.used?Object.assign(b,f):(d.target=f,f);// no cycle, can just use the returned read object
45
45
  },K[112]=()=>{// pointer extension (for structured clones)
46
46
  let a=F.getUint32(G-4),b=E.get(a);return b.used=!0,b.target},K[115]=()=>new Set(e());const $=["Int8","Uint8","Uint8Clamped","Int16","Uint16","Int32","Uint32","Float32","Float64","BigInt64","BigUint64"].map(a=>a+"Array");K[116]=a=>{let b=a[0],c=$[b];if(!c)throw new Error("Could not find typed array for code "+b);// we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned
47
- return new Z[c](Uint8Array.prototype.slice.call(a,1).buffer)},K[120]=()=>{let a=e();return new RegExp(a[0],a[1])},K[255]=a=>{// 32-bit date extension
48
- if(4==a.length)return new Date(1e3*(16777216*a[0]+(a[1]<<16)+(a[2]<<8)+a[3]));if(8==a.length)return new Date(((a[0]<<22)+(a[1]<<14)+(a[2]<<6)+(a[3]>>2))/1e6+1e3*(4294967296*(3&a[3])+16777216*a[4]+(a[5]<<16)+(a[6]<<8)+a[7]));if(12==a.length)// TODO: Implement support for negative
49
- return new Date(((a[0]<<24)+(a[1]<<16)+(a[2]<<8)+a[3])/1e6+1e3*((128&a[4]?-281474976710656:0)+1099511627776*a[6]+4294967296*a[7]+16777216*a[8]+(a[9]<<16)+(a[10]<<8)+a[11]));throw new Error("Invalid timestamp length")};const _=Array(147);// this is a table matching binary exponents to the multiplier to determine significant digit rounding
47
+ return new Z[c](Uint8Array.prototype.slice.call(a,1).buffer)},K[120]=()=>{let a=e();return new RegExp(a[0],a[1])},K[255]=a=>4==a.length?new Date(1e3*(16777216*a[0]+(a[1]<<16)+(a[2]<<8)+a[3])):8==a.length?new Date(((a[0]<<22)+(a[1]<<14)+(a[2]<<6)+(a[3]>>2))/1e6+1e3*(4294967296*(3&a[3])+16777216*a[4]+(a[5]<<16)+(a[6]<<8)+a[7])):12==a.length?new Date(((a[0]<<24)+(a[1]<<16)+(a[2]<<8)+a[3])/1e6+1e3*((128&a[4]?-281474976710656:0)+1099511627776*a[6]+4294967296*a[7]+16777216*a[8]+(a[9]<<16)+(a[10]<<8)+a[11])):new Date("invalid");const _=Array(147);// this is a table matching binary exponents to the multiplier to determine significant digit rounding
50
48
  for(let c=0;256>c;c++)_[c]=+("1e"+b(45.15-.30103*c));var aa=new P({useRecords:!1});const ba=aa.unpack,ca=aa.unpackMultiple,da=aa.unpack,ea={NEVER:0,ALWAYS:1,DECIMAL_ROUND:3,DECIMAL_FIT:4};let fa,ga=new Float32Array(1),ha=new Uint8Array(ga.buffer,0,4);try{fa=new TextEncoder}catch(a){}let ia,ja;const ka="undefined"!=typeof Buffer,la=ka?Buffer.allocUnsafeSlow:Uint8Array,ma=ka?Buffer:Uint8Array,na=ka?4294967296:2144337920;let oa,pa,qa,ra=0;const sa=Symbol("record-id");class ta extends P{constructor(a){super(a),this.offset=0;let b,c,d,e,f,g=0,h=ma.prototype.utf8Write?function(a,b,c){return oa.utf8Write(a,b,c)}:!!(fa&&fa.encodeInto)&&function(a,b){return fa.encodeInto(a,oa.subarray(b)).written},i=this;a||(a={});let j=a&&a.sequential,k=a.structures||a.saveStructures,l=a.maxSharedStructures;if(null==l&&(l=k?32:0),8160<l)throw new Error("Maximum maxSharedStructure is 8160");let m=a.maxOwnStructures;null==m&&(m=k?32:64),j&&!a.saveStructures&&(this.structures=[]);// two byte record ids for shared structures
51
49
  let n=32<l||64<m+l,o=l+64,p=l+m+64;if(8256<p)throw new Error("Maximum maxSharedStructure + maxOwnStructure is 8192");let q=[],r=0,s=0;this.pack=this.encode=function(a,h){if(oa||(oa=new la(8192),pa=new DataView(oa.buffer,0,8192),ra=0),qa=oa.length-10,2048>qa-ra?(oa=new la(oa.length),pa=new DataView(oa.buffer,0,oa.length),qa=oa.length-10,ra=0):ra=2147483640&ra+7,b=ra,f=i.structuredClone?new Map:null,c=i.structures,c){c.uninitialized&&(c=i._mergeStructures(i.getStructures()));let a=c.sharedLength||0;if(a>l)//if (maxSharedStructures <= 32 && sharedStructures.sharedLength > 32) // TODO: could support this, but would need to update the limit ids
52
50
  throw new Error("Shared structures is larger than maximum shared structures, try increasing maxSharedStructures to "+c.sharedLength);if(!c.transitions){c.transitions=Object.create(null);for(let b,d=0;d<a;d++){if(b=c[d],!b)continue;let a,e=c.transitions;for(let c,d=0,f=b.length;d<f;d++)c=b[d],a=e[c],a||(a=e[c]=Object.create(null)),e=a;e[sa]=d+64}g=a}j||(c.nextId=a+64)}d&&(d=!1),e=c||[];try{// update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
@@ -102,10 +100,11 @@ h=o),e.nextId=h+1);let a=c.highByte=96<=h&&n?h-96>>5:-1;f[sa]=h,e[h-64]=c,h<o?(c
102
100
  for(let b=0,d=c.length;b<d;b++)t(a[c[b]])},x=a=>{var c=Math.min,d=Math.round,e=Math.max;let f;if(16777216<a){// special handling for really large buffers
103
101
  if(a-b>na)throw new Error("Packed buffer would be larger than maximum buffer size");f=c(na,4096*d(e((a-b)*(67108864<a?1.25:2),4194304)/4096))}else// faster handling for smaller buffers
104
102
  f=(e(a-b<<2,oa.length-1)>>12)+1<<12;let g=new la(f);return pa=new DataView(g.buffer,0,f),oa.copy?oa.copy(g,0,b,a):g.set(oa.slice(b,a)),ra-=b,b=0,qa=g.length-10,oa=g}}useBuffer(a){// this means we are finished using our own buffer and we can write over it safely
105
- oa=a,pa=new DataView(oa.buffer,oa.byteOffset,oa.byteLength),ra=0}}ja=[Date,Set,Error,RegExp,ArrayBuffer,Object.getPrototypeOf(Uint8Array.prototype).constructor/*TypedArray*/,M],ia=[{pack(a,c){let d=a.getTime()/1e3;if((this.useTimestamp32||0===a.getMilliseconds())&&0<=d&&4294967296>d){// Timestamp 32
106
- let{target:a,targetView:b,position:e}=c(6);a[e++]=214,a[e++]=255,b.setUint32(e,d)}else if(0<d&&17179869184>d){// Timestamp 64
107
- let{target:b,targetView:e,position:f}=c(10);b[f++]=215,b[f++]=255,e.setUint32(f,4e6*a.getMilliseconds()+(d/1e3/4294967296>>0)),e.setUint32(f+4,d)}else{// Timestamp 96
108
- let{target:e,targetView:f,position:g}=c(15);e[g++]=199,e[g++]=12,e[g++]=255,f.setUint32(g,1e6*a.getMilliseconds()),f.setBigInt64(g+4,BigInt(b(d)))}}},{pack(a,b,c){let d=Array.from(a),{target:e,position:f}=b(this.structuredClone?3:0);this.structuredClone&&(e[f++]=212,e[f++]=115,e[f++]=0),c(d)}},{pack(a,b,c){let{target:d,position:e}=b(this.structuredClone?3:0);this.structuredClone&&(d[e++]=212,d[e++]=101,d[e++]=0),c([a.name,a.message])}},{pack(a,b,c){let{target:d,position:e}=b(this.structuredClone?3:0);this.structuredClone&&(d[e++]=212,d[e++]=120,d[e++]=0),c([a.source,a.flags])}},{pack(a,b){this.structuredClone?s(a,16,b):t(ka?Buffer.from(a):new Uint8Array(a),b)}},{pack(a,b){let c=a.constructor;c!==ma&&this.structuredClone?s(a,$.indexOf(c.name),b):t(a,b)}},{pack(a,b){// specific 0xC1 object
103
+ oa=a,pa=new DataView(oa.buffer,oa.byteOffset,oa.byteLength),ra=0}}ja=[Date,Set,Error,RegExp,ArrayBuffer,Object.getPrototypeOf(Uint8Array.prototype).constructor/*TypedArray*/,M],ia=[{pack(a,c,d){let e=a.getTime()/1e3;if((this.useTimestamp32||0===a.getMilliseconds())&&0<=e&&4294967296>e){// Timestamp 32
104
+ let{target:a,targetView:b,position:d}=c(6);a[d++]=214,a[d++]=255,b.setUint32(d,e)}else if(0<e&&17179869184>e){// Timestamp 64
105
+ let{target:b,targetView:d,position:f}=c(10);b[f++]=215,b[f++]=255,d.setUint32(f,4e6*a.getMilliseconds()+(e/1e3/4294967296>>0)),d.setUint32(f+4,e)}else if(isNaN(e)){if(this.onInvalidDate)return d(this.onInvalidDate());// Intentionally invalid timestamp
106
+ let{target:a,targetView:b,position:e}=c(3);a[e++]=212,a[e++]=255,a[e++]=255}else{// Timestamp 96
107
+ let{target:d,targetView:f,position:g}=c(15);d[g++]=199,d[g++]=12,d[g++]=255,f.setUint32(g,1e6*a.getMilliseconds()),f.setBigInt64(g+4,BigInt(b(e)))}}},{pack(a,b,c){let d=Array.from(a),{target:e,position:f}=b(this.structuredClone?3:0);this.structuredClone&&(e[f++]=212,e[f++]=115,e[f++]=0),c(d)}},{pack(a,b,c){let{target:d,position:e}=b(this.structuredClone?3:0);this.structuredClone&&(d[e++]=212,d[e++]=101,d[e++]=0),c([a.name,a.message])}},{pack(a,b,c){let{target:d,position:e}=b(this.structuredClone?3:0);this.structuredClone&&(d[e++]=212,d[e++]=120,d[e++]=0),c([a.source,a.flags])}},{pack(a,b){this.structuredClone?s(a,16,b):t(ka?Buffer.from(a):new Uint8Array(a),b)}},{pack(a,b){let c=a.constructor;c!==ma&&this.structuredClone?s(a,$.indexOf(c.name),b):t(a,b)}},{pack(a,b){// specific 0xC1 object
109
108
  let{target:c,position:d}=b(1);c[d]=193}}];let ua=new ta({useRecords:!1});const va=ua.pack,wa=ua.pack,{NEVER:xa,ALWAYS:ya,DECIMAL_ROUND:za,DECIMAL_FIT:Aa}=ea,Ba=1e3;a.ALWAYS=ya,a.C1=N,a.DECIMAL_FIT=Aa,a.DECIMAL_ROUND=za,a.Decoder=P,a.Encoder=ta,a.FLOAT32_OPTIONS=ea,a.NEVER=xa,a.Packr=ta,a.REUSE_BUFFER_MODE=Ba,a.Unpackr=P,a.addExtension=w,a.clearSource=q,a.decode=da,a.decodeIter=function(a,b={}){if(!a||"object"!=typeof a)throw new Error("first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise");const c=new P(b);let d;const e=a=>{let b;// if there's incomplete data from previous chunk, concatinate and try again
110
109
  d&&(a=Buffer.concat([d,a]),d=void 0);try{b=c.unpackMultiple(a)}catch(c){if(c.incomplete)d=a.slice(c.lastPosition),b=c.values;else throw c}return b};if("function"==typeof a[Symbol.iterator])return function*(){for(const b of a)yield*e(b)}();return"function"==typeof a[Symbol.asyncIterator]?async function*(){for await(const b of a)yield*e(b)}():void 0},a.encode=wa,a.encodeIter=/**
111
110
  * Given an Iterable first argument, returns an Iterable where each value is packed as a Buffer
package/dist/node.cjs CHANGED
@@ -913,7 +913,7 @@ currentExtensions[0xff] = (data) => {
913
913
  ((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]) / 1000000 +
914
914
  (((data[4] & 0x80) ? -0x1000000000000 : 0) + data[6] * 0x10000000000 + data[7] * 0x100000000 + data[8] * 0x1000000 + (data[9] << 16) + (data[10] << 8) + data[11]) * 1000)
915
915
  else
916
- throw new Error('Invalid timestamp length')
916
+ return new Date('invalid')
917
917
  }; // notepack defines extension 0 to mean undefined, so use that as the default here
918
918
  // registration of bulk record definition?
919
919
  // currentExtensions[0x52] = () =>
@@ -1602,7 +1602,7 @@ class Packr extends Unpackr {
1602
1602
 
1603
1603
  extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, C1Type ];
1604
1604
  extensions = [{
1605
- pack(date, allocateForWrite) {
1605
+ pack(date, allocateForWrite, pack) {
1606
1606
  let seconds = date.getTime() / 1000;
1607
1607
  if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
1608
1608
  // Timestamp 32
@@ -1617,6 +1617,14 @@ extensions = [{
1617
1617
  target[position++] = 0xff;
1618
1618
  targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0));
1619
1619
  targetView.setUint32(position + 4, seconds);
1620
+ } else if (isNaN(seconds)) {
1621
+ if (this.onInvalidDate)
1622
+ return pack(this.onInvalidDate())
1623
+ // Intentionally invalid timestamp
1624
+ let { target, targetView, position} = allocateForWrite(3);
1625
+ target[position++] = 0xd4;
1626
+ target[position++] = 0xff;
1627
+ target[position++] = 0xff;
1620
1628
  } else {
1621
1629
  // Timestamp 96
1622
1630
  let { target, targetView, position} = allocateForWrite(15);
package/dist/str.cjs ADDED
@@ -0,0 +1,100 @@
1
+ let utfz = require('../../msgpack-benchmark/node_modules/utfz-lib')
2
+
3
+ var safeEnd = 1000000;
4
+ var b = new Uint8Array(32768)
5
+ function writeString(value, target, position) {
6
+ var length, strLength = value.length;
7
+ let headerSize;
8
+ // first we estimate the header size, so we can write to the correct location
9
+ if (strLength < 0x20) {
10
+ headerSize = 1;
11
+ } else if (strLength < 0x100) {
12
+ headerSize = 2;
13
+ } else if (strLength < 0x10000) {
14
+ headerSize = 3;
15
+ } else {
16
+ headerSize = 5;
17
+ }
18
+ let maxBytes = strLength * 3;
19
+ //if (position + maxBytes > safeEnd)
20
+ // target = makeRoom(position + maxBytes);
21
+ for (let i = 0; i < 100; i++) {
22
+ length = pack(value, strLength, target, position + headerSize);
23
+ }
24
+ if (strLength < 0x40 || !encodeUtf8) {
25
+ var strPosition = position + headerSize;
26
+ var c2 = 0;
27
+ for (let i = 0; i < strLength; i++) {
28
+ const c1 = value.charCodeAt(i);
29
+ if (c1 < 0x80) {
30
+ target[strPosition++] = c1;
31
+ } else if (c1 < 0x800) {
32
+ target[strPosition++] = c1 >> 6 | 0xc0;
33
+ target[strPosition++] = c1 & 0x3f | 0x80;
34
+ } else if (
35
+ (c1 & 0xfc00) === 0xd800 &&
36
+ ((c2 = value.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
37
+ ) {
38
+ c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff);
39
+ i++;
40
+ target[strPosition++] = c1 >> 18 | 0xf0;
41
+ target[strPosition++] = c1 >> 12 & 0x3f | 0x80;
42
+ target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
43
+ target[strPosition++] = c1 & 0x3f | 0x80;
44
+ } else {
45
+ target[strPosition++] = c1 >> 12 | 0xe0;
46
+ target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
47
+ target[strPosition++] = c1 & 0x3f | 0x80;
48
+ }
49
+ }
50
+ length = strPosition - position - headerSize;
51
+ } else {
52
+ length = encodeUtf8(value, position + headerSize, maxBytes);
53
+ }
54
+
55
+
56
+ if (length < 0x20) {
57
+ target[position++] = 0xa0 | length;
58
+ } else if (length < 0x100) {
59
+ if (headerSize < 2) {
60
+ target.copyWithin(position + 2, position + 1, position + 1 + length);
61
+ }
62
+ target[position++] = 0xd9;
63
+ target[position++] = length;
64
+ } else if (length < 0x10000) {
65
+ if (headerSize < 3) {
66
+ target.copyWithin(position + 3, position + 2, position + 2 + length);
67
+ }
68
+ target[position++] = 0xda;
69
+ target[position++] = length >> 8;
70
+ target[position++] = length & 0xff;
71
+ } else {
72
+ if (headerSize < 5) {
73
+ target.copyWithin(position + 5, position + 3, position + 3 + length);
74
+ }
75
+ target[position++] = 0xdb;
76
+ targetView.setUint32(position, length);
77
+ position += 4;
78
+ }
79
+ return position + length
80
+ };
81
+ const pack = (str, length, buf, offset) => {
82
+ const start = offset;
83
+ let currHigh = 0;
84
+ for (let i = 0; i < length; i++) {
85
+ const code = str.charCodeAt(i);
86
+ const high = code >> 8;
87
+ if (high !== currHigh) {
88
+ buf[i + offset++] = 0;
89
+ buf[i + offset++] = high;
90
+ currHigh = high;
91
+ }
92
+ const low = code & 0xff;
93
+ buf[i + offset] = low;
94
+ if (!low) {
95
+ buf[i + ++offset] = currHigh;
96
+ }
97
+ }
98
+ return length + offset - start;
99
+ };
100
+ module.exports = writeString;
package/dist/test.js CHANGED
@@ -989,6 +989,7 @@
989
989
  date: new Date(1532219539733),
990
990
  farFutureDate: new Date(3532219539133),
991
991
  ancient: new Date(-3532219539133),
992
+ invalidDate: new Date('invalid')
992
993
  };
993
994
  let packr = new Packr();
994
995
  var serialized = packr.pack(data);
@@ -998,6 +999,7 @@
998
999
  assert.equal(deserialized.date.getTime(), 1532219539733);
999
1000
  assert.equal(deserialized.farFutureDate.getTime(), 3532219539133);
1000
1001
  assert.equal(deserialized.ancient.getTime(), -3532219539133);
1002
+ assert.equal(deserialized.invalidDate.toString(), 'Invalid Date');
1001
1003
  });
1002
1004
  test('map/date with options', function(){
1003
1005
  var map = new Map();
package/pack.js CHANGED
@@ -622,7 +622,7 @@ function copyBinary(source, target, targetOffset, offset, endOffset) {
622
622
 
623
623
  extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, C1Type ]
624
624
  extensions = [{
625
- pack(date, allocateForWrite) {
625
+ pack(date, allocateForWrite, pack) {
626
626
  let seconds = date.getTime() / 1000
627
627
  if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
628
628
  // Timestamp 32
@@ -637,6 +637,14 @@ extensions = [{
637
637
  target[position++] = 0xff
638
638
  targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0))
639
639
  targetView.setUint32(position + 4, seconds)
640
+ } else if (isNaN(seconds)) {
641
+ if (this.onInvalidDate)
642
+ return pack(this.onInvalidDate())
643
+ // Intentionally invalid timestamp
644
+ let { target, targetView, position} = allocateForWrite(3)
645
+ target[position++] = 0xd4
646
+ target[position++] = 0xff
647
+ target[position++] = 0xff
640
648
  } else {
641
649
  // Timestamp 96
642
650
  let { target, targetView, position} = allocateForWrite(15)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "msgpackr",
3
3
  "author": "Kris Zyp",
4
- "version": "1.5.0",
4
+ "version": "1.5.1",
5
5
  "description": "Ultra-fast MessagePack implementation with extensions for records and structured cloning",
6
6
  "license": "MIT",
7
7
  "types": "./index.d.ts",
package/tests/test.js CHANGED
@@ -416,6 +416,7 @@ suite('msgpackr basic tests', function(){
416
416
  date: new Date(1532219539733),
417
417
  farFutureDate: new Date(3532219539133),
418
418
  ancient: new Date(-3532219539133),
419
+ invalidDate: new Date('invalid')
419
420
  }
420
421
  let packr = new Packr()
421
422
  var serialized = packr.pack(data)
@@ -425,6 +426,7 @@ suite('msgpackr basic tests', function(){
425
426
  assert.equal(deserialized.date.getTime(), 1532219539733)
426
427
  assert.equal(deserialized.farFutureDate.getTime(), 3532219539133)
427
428
  assert.equal(deserialized.ancient.getTime(), -3532219539133)
429
+ assert.equal(deserialized.invalidDate.toString(), 'Invalid Date')
428
430
  })
429
431
  test('map/date with options', function(){
430
432
  var map = new Map()
package/unpack.js CHANGED
@@ -911,7 +911,7 @@ currentExtensions[0xff] = (data) => {
911
911
  ((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]) / 1000000 +
912
912
  (((data[4] & 0x80) ? -0x1000000000000 : 0) + data[6] * 0x10000000000 + data[7] * 0x100000000 + data[8] * 0x1000000 + (data[9] << 16) + (data[10] << 8) + data[11]) * 1000)
913
913
  else
914
- throw new Error('Invalid timestamp length')
914
+ return new Date('invalid')
915
915
  } // notepack defines extension 0 to mean undefined, so use that as the default here
916
916
  // registration of bulk record definition?
917
917
  // currentExtensions[0x52] = () =>