test.js 142 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379
  1. (function (chai, stream, module, fs) {
  2. 'use strict';
  3. var decoder;
  4. try {
  5. decoder = new TextDecoder();
  6. } catch(error) {}
  7. var src;
  8. var srcEnd;
  9. var position$1 = 0;
  10. const EMPTY_ARRAY = [];
  11. var strings = EMPTY_ARRAY;
  12. var stringPosition = 0;
  13. var currentUnpackr = {};
  14. var currentStructures;
  15. var srcString;
  16. var srcStringStart = 0;
  17. var srcStringEnd = 0;
  18. var bundledStrings$1;
  19. var referenceMap;
  20. var currentExtensions = [];
  21. var dataView;
  22. var defaultOptions = {
  23. useRecords: false,
  24. mapsAsObjects: true
  25. };
  26. class C1Type {}
  27. const C1 = new C1Type();
  28. C1.name = 'MessagePack 0xC1';
  29. var sequentialMode = false;
  30. var inlineObjectReadThreshold = 2;
  31. var readStruct$1, onLoadedStructures$1, onSaveState;
  32. // no-eval build
  33. try {
  34. new Function('');
  35. } catch(error) {
  36. // if eval variants are not supported, do not create inline object readers ever
  37. inlineObjectReadThreshold = Infinity;
  38. }
  39. let Unpackr$1 = class Unpackr {
  40. constructor(options) {
  41. if (options) {
  42. if (options.useRecords === false && options.mapsAsObjects === undefined)
  43. options.mapsAsObjects = true;
  44. if (options.sequential && options.trusted !== false) {
  45. options.trusted = true;
  46. if (!options.structures && options.useRecords != false) {
  47. options.structures = [];
  48. if (!options.maxSharedStructures)
  49. options.maxSharedStructures = 0;
  50. }
  51. }
  52. if (options.structures)
  53. options.structures.sharedLength = options.structures.length;
  54. else if (options.getStructures) {
  55. (options.structures = []).uninitialized = true; // this is what we use to denote an uninitialized structures
  56. options.structures.sharedLength = 0;
  57. }
  58. if (options.int64AsNumber) {
  59. options.int64AsType = 'number';
  60. }
  61. }
  62. Object.assign(this, options);
  63. }
  64. unpack(source, options) {
  65. if (src) {
  66. // re-entrant execution, save the state and restore it after we do this unpack
  67. return saveState$1(() => {
  68. clearSource();
  69. return this ? this.unpack(source, options) : Unpackr$1.prototype.unpack.call(defaultOptions, source, options)
  70. })
  71. }
  72. if (!source.buffer && source.constructor === ArrayBuffer)
  73. source = typeof Buffer !== 'undefined' ? Buffer.from(source) : new Uint8Array(source);
  74. if (typeof options === 'object') {
  75. srcEnd = options.end || source.length;
  76. position$1 = options.start || 0;
  77. } else {
  78. position$1 = 0;
  79. srcEnd = options > -1 ? options : source.length;
  80. }
  81. stringPosition = 0;
  82. srcStringEnd = 0;
  83. srcString = null;
  84. strings = EMPTY_ARRAY;
  85. bundledStrings$1 = null;
  86. src = source;
  87. // this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
  88. // technique for getting data from a database where it can be copied into an existing buffer instead of creating
  89. // new ones
  90. try {
  91. dataView = source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength));
  92. } catch(error) {
  93. // if it doesn't have a buffer, maybe it is the wrong type of object
  94. src = null;
  95. if (source instanceof Uint8Array)
  96. throw error
  97. throw new Error('Source must be a Uint8Array or Buffer but was a ' + ((source && typeof source == 'object') ? source.constructor.name : typeof source))
  98. }
  99. if (this instanceof Unpackr$1) {
  100. currentUnpackr = this;
  101. if (this.structures) {
  102. currentStructures = this.structures;
  103. return checkedRead(options)
  104. } else if (!currentStructures || currentStructures.length > 0) {
  105. currentStructures = [];
  106. }
  107. } else {
  108. currentUnpackr = defaultOptions;
  109. if (!currentStructures || currentStructures.length > 0)
  110. currentStructures = [];
  111. }
  112. return checkedRead(options)
  113. }
  114. unpackMultiple(source, forEach) {
  115. let values, lastPosition = 0;
  116. try {
  117. sequentialMode = true;
  118. let size = source.length;
  119. let value = this ? this.unpack(source, size) : defaultUnpackr.unpack(source, size);
  120. if (forEach) {
  121. if (forEach(value, lastPosition, position$1) === false) return;
  122. while(position$1 < size) {
  123. lastPosition = position$1;
  124. if (forEach(checkedRead(), lastPosition, position$1) === false) {
  125. return
  126. }
  127. }
  128. }
  129. else {
  130. values = [ value ];
  131. while(position$1 < size) {
  132. lastPosition = position$1;
  133. values.push(checkedRead());
  134. }
  135. return values
  136. }
  137. } catch(error) {
  138. error.lastPosition = lastPosition;
  139. error.values = values;
  140. throw error
  141. } finally {
  142. sequentialMode = false;
  143. clearSource();
  144. }
  145. }
  146. _mergeStructures(loadedStructures, existingStructures) {
  147. if (onLoadedStructures$1)
  148. loadedStructures = onLoadedStructures$1.call(this, loadedStructures);
  149. loadedStructures = loadedStructures || [];
  150. if (Object.isFrozen(loadedStructures))
  151. loadedStructures = loadedStructures.map(structure => structure.slice(0));
  152. for (let i = 0, l = loadedStructures.length; i < l; i++) {
  153. let structure = loadedStructures[i];
  154. if (structure) {
  155. structure.isShared = true;
  156. if (i >= 32)
  157. structure.highByte = (i - 32) >> 5;
  158. }
  159. }
  160. loadedStructures.sharedLength = loadedStructures.length;
  161. for (let id in existingStructures || []) {
  162. if (id >= 0) {
  163. let structure = loadedStructures[id];
  164. let existing = existingStructures[id];
  165. if (existing) {
  166. if (structure)
  167. (loadedStructures.restoreStructures || (loadedStructures.restoreStructures = []))[id] = structure;
  168. loadedStructures[id] = existing;
  169. }
  170. }
  171. }
  172. return this.structures = loadedStructures
  173. }
  174. decode(source, options) {
  175. return this.unpack(source, options)
  176. }
  177. };
  178. function checkedRead(options) {
  179. try {
  180. if (!currentUnpackr.trusted && !sequentialMode) {
  181. let sharedLength = currentStructures.sharedLength || 0;
  182. if (sharedLength < currentStructures.length)
  183. currentStructures.length = sharedLength;
  184. }
  185. let result;
  186. if (currentUnpackr.randomAccessStructure && src[position$1] < 0x40 && src[position$1] >= 0x20 && readStruct$1) {
  187. result = readStruct$1(src, position$1, srcEnd, currentUnpackr);
  188. src = null; // dispose of this so that recursive unpack calls don't save state
  189. if (!(options && options.lazy) && result)
  190. result = result.toJSON();
  191. position$1 = srcEnd;
  192. } else
  193. result = read();
  194. if (bundledStrings$1) { // bundled strings to skip past
  195. position$1 = bundledStrings$1.postBundlePosition;
  196. bundledStrings$1 = null;
  197. }
  198. if (sequentialMode)
  199. // we only need to restore the structures if there was an error, but if we completed a read,
  200. // we can clear this out and keep the structures we read
  201. currentStructures.restoreStructures = null;
  202. if (position$1 == srcEnd) {
  203. // finished reading this source, cleanup references
  204. if (currentStructures && currentStructures.restoreStructures)
  205. restoreStructures();
  206. currentStructures = null;
  207. src = null;
  208. if (referenceMap)
  209. referenceMap = null;
  210. } else if (position$1 > srcEnd) {
  211. // over read
  212. throw new Error('Unexpected end of MessagePack data')
  213. } else if (!sequentialMode) {
  214. let jsonView;
  215. try {
  216. jsonView = JSON.stringify(result, (_, value) => typeof value === "bigint" ? `${value}n` : value).slice(0, 100);
  217. } catch(error) {
  218. jsonView = '(JSON view not available ' + error + ')';
  219. }
  220. throw new Error('Data read, but end of buffer not reached ' + jsonView)
  221. }
  222. // else more to read, but we are reading sequentially, so don't clear source yet
  223. return result
  224. } catch(error) {
  225. if (currentStructures && currentStructures.restoreStructures)
  226. restoreStructures();
  227. clearSource();
  228. if (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer') || position$1 > srcEnd) {
  229. error.incomplete = true;
  230. }
  231. throw error
  232. }
  233. }
  234. function restoreStructures() {
  235. for (let id in currentStructures.restoreStructures) {
  236. currentStructures[id] = currentStructures.restoreStructures[id];
  237. }
  238. currentStructures.restoreStructures = null;
  239. }
  240. function read() {
  241. let token = src[position$1++];
  242. if (token < 0xa0) {
  243. if (token < 0x80) {
  244. if (token < 0x40)
  245. return token
  246. else {
  247. let structure = currentStructures[token & 0x3f] ||
  248. currentUnpackr.getStructures && loadStructures()[token & 0x3f];
  249. if (structure) {
  250. if (!structure.read) {
  251. structure.read = createStructureReader(structure, token & 0x3f);
  252. }
  253. return structure.read()
  254. } else
  255. return token
  256. }
  257. } else if (token < 0x90) {
  258. // map
  259. token -= 0x80;
  260. if (currentUnpackr.mapsAsObjects) {
  261. let object = {};
  262. for (let i = 0; i < token; i++) {
  263. let key = readKey();
  264. if (key === '__proto__')
  265. key = '__proto_';
  266. object[key] = read();
  267. }
  268. return object
  269. } else {
  270. let map = new Map();
  271. for (let i = 0; i < token; i++) {
  272. map.set(read(), read());
  273. }
  274. return map
  275. }
  276. } else {
  277. token -= 0x90;
  278. let array = new Array(token);
  279. for (let i = 0; i < token; i++) {
  280. array[i] = read();
  281. }
  282. if (currentUnpackr.freezeData)
  283. return Object.freeze(array)
  284. return array
  285. }
  286. } else if (token < 0xc0) {
  287. // fixstr
  288. let length = token - 0xa0;
  289. if (srcStringEnd >= position$1) {
  290. return srcString.slice(position$1 - srcStringStart, (position$1 += length) - srcStringStart)
  291. }
  292. if (srcStringEnd == 0 && srcEnd < 140) {
  293. // for small blocks, avoiding the overhead of the extract call is helpful
  294. let string = length < 16 ? shortStringInJS(length) : longStringInJS(length);
  295. if (string != null)
  296. return string
  297. }
  298. return readFixedString(length)
  299. } else {
  300. let value;
  301. switch (token) {
  302. case 0xc0: return null
  303. case 0xc1:
  304. if (bundledStrings$1) {
  305. value = read(); // followed by the length of the string in characters (not bytes!)
  306. if (value > 0)
  307. return bundledStrings$1[1].slice(bundledStrings$1.position1, bundledStrings$1.position1 += value)
  308. else
  309. return bundledStrings$1[0].slice(bundledStrings$1.position0, bundledStrings$1.position0 -= value)
  310. }
  311. return C1; // "never-used", return special object to denote that
  312. case 0xc2: return false
  313. case 0xc3: return true
  314. case 0xc4:
  315. // bin 8
  316. value = src[position$1++];
  317. if (value === undefined)
  318. throw new Error('Unexpected end of buffer')
  319. return readBin(value)
  320. case 0xc5:
  321. // bin 16
  322. value = dataView.getUint16(position$1);
  323. position$1 += 2;
  324. return readBin(value)
  325. case 0xc6:
  326. // bin 32
  327. value = dataView.getUint32(position$1);
  328. position$1 += 4;
  329. return readBin(value)
  330. case 0xc7:
  331. // ext 8
  332. return readExt(src[position$1++])
  333. case 0xc8:
  334. // ext 16
  335. value = dataView.getUint16(position$1);
  336. position$1 += 2;
  337. return readExt(value)
  338. case 0xc9:
  339. // ext 32
  340. value = dataView.getUint32(position$1);
  341. position$1 += 4;
  342. return readExt(value)
  343. case 0xca:
  344. value = dataView.getFloat32(position$1);
  345. if (currentUnpackr.useFloat32 > 2) {
  346. // this does rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
  347. let multiplier = mult10[((src[position$1] & 0x7f) << 1) | (src[position$1 + 1] >> 7)];
  348. position$1 += 4;
  349. return ((multiplier * value + (value > 0 ? 0.5 : -0.5)) >> 0) / multiplier
  350. }
  351. position$1 += 4;
  352. return value
  353. case 0xcb:
  354. value = dataView.getFloat64(position$1);
  355. position$1 += 8;
  356. return value
  357. // uint handlers
  358. case 0xcc:
  359. return src[position$1++]
  360. case 0xcd:
  361. value = dataView.getUint16(position$1);
  362. position$1 += 2;
  363. return value
  364. case 0xce:
  365. value = dataView.getUint32(position$1);
  366. position$1 += 4;
  367. return value
  368. case 0xcf:
  369. if (currentUnpackr.int64AsType === 'number') {
  370. value = dataView.getUint32(position$1) * 0x100000000;
  371. value += dataView.getUint32(position$1 + 4);
  372. } else if (currentUnpackr.int64AsType === 'string') {
  373. value = dataView.getBigUint64(position$1).toString();
  374. } else if (currentUnpackr.int64AsType === 'auto') {
  375. value = dataView.getBigUint64(position$1);
  376. if (value<=BigInt(2)<<BigInt(52)) value=Number(value);
  377. } else
  378. value = dataView.getBigUint64(position$1);
  379. position$1 += 8;
  380. return value
  381. // int handlers
  382. case 0xd0:
  383. return dataView.getInt8(position$1++)
  384. case 0xd1:
  385. value = dataView.getInt16(position$1);
  386. position$1 += 2;
  387. return value
  388. case 0xd2:
  389. value = dataView.getInt32(position$1);
  390. position$1 += 4;
  391. return value
  392. case 0xd3:
  393. if (currentUnpackr.int64AsType === 'number') {
  394. value = dataView.getInt32(position$1) * 0x100000000;
  395. value += dataView.getUint32(position$1 + 4);
  396. } else if (currentUnpackr.int64AsType === 'string') {
  397. value = dataView.getBigInt64(position$1).toString();
  398. } else if (currentUnpackr.int64AsType === 'auto') {
  399. value = dataView.getBigInt64(position$1);
  400. if (value>=BigInt(-2)<<BigInt(52)&&value<=BigInt(2)<<BigInt(52)) value=Number(value);
  401. } else
  402. value = dataView.getBigInt64(position$1);
  403. position$1 += 8;
  404. return value
  405. case 0xd4:
  406. // fixext 1
  407. value = src[position$1++];
  408. if (value == 0x72) {
  409. return recordDefinition(src[position$1++] & 0x3f)
  410. } else {
  411. let extension = currentExtensions[value];
  412. if (extension) {
  413. if (extension.read) {
  414. position$1++; // skip filler byte
  415. return extension.read(read())
  416. } else if (extension.noBuffer) {
  417. position$1++; // skip filler byte
  418. return extension()
  419. } else
  420. return extension(src.subarray(position$1, ++position$1))
  421. } else
  422. throw new Error('Unknown extension ' + value)
  423. }
  424. case 0xd5:
  425. // fixext 2
  426. value = src[position$1];
  427. if (value == 0x72) {
  428. position$1++;
  429. return recordDefinition(src[position$1++] & 0x3f, src[position$1++])
  430. } else
  431. return readExt(2)
  432. case 0xd6:
  433. // fixext 4
  434. return readExt(4)
  435. case 0xd7:
  436. // fixext 8
  437. return readExt(8)
  438. case 0xd8:
  439. // fixext 16
  440. return readExt(16)
  441. case 0xd9:
  442. // str 8
  443. value = src[position$1++];
  444. if (srcStringEnd >= position$1) {
  445. return srcString.slice(position$1 - srcStringStart, (position$1 += value) - srcStringStart)
  446. }
  447. return readString8(value)
  448. case 0xda:
  449. // str 16
  450. value = dataView.getUint16(position$1);
  451. position$1 += 2;
  452. if (srcStringEnd >= position$1) {
  453. return srcString.slice(position$1 - srcStringStart, (position$1 += value) - srcStringStart)
  454. }
  455. return readString16(value)
  456. case 0xdb:
  457. // str 32
  458. value = dataView.getUint32(position$1);
  459. position$1 += 4;
  460. if (srcStringEnd >= position$1) {
  461. return srcString.slice(position$1 - srcStringStart, (position$1 += value) - srcStringStart)
  462. }
  463. return readString32(value)
  464. case 0xdc:
  465. // array 16
  466. value = dataView.getUint16(position$1);
  467. position$1 += 2;
  468. return readArray(value)
  469. case 0xdd:
  470. // array 32
  471. value = dataView.getUint32(position$1);
  472. position$1 += 4;
  473. return readArray(value)
  474. case 0xde:
  475. // map 16
  476. value = dataView.getUint16(position$1);
  477. position$1 += 2;
  478. return readMap(value)
  479. case 0xdf:
  480. // map 32
  481. value = dataView.getUint32(position$1);
  482. position$1 += 4;
  483. return readMap(value)
  484. default: // negative int
  485. if (token >= 0xe0)
  486. return token - 0x100
  487. if (token === undefined) {
  488. let error = new Error('Unexpected end of MessagePack data');
  489. error.incomplete = true;
  490. throw error
  491. }
  492. throw new Error('Unknown MessagePack token ' + token)
  493. }
  494. }
  495. }
  496. const validName = /^[a-zA-Z_$][a-zA-Z\d_$]*$/;
  497. function createStructureReader(structure, firstId) {
  498. function readObject() {
  499. // This initial function is quick to instantiate, but runs slower. After several iterations pay the cost to build the faster function
  500. if (readObject.count++ > inlineObjectReadThreshold) {
  501. let readObject = structure.read = (new Function('r', 'return function(){return ' + (currentUnpackr.freezeData ? 'Object.freeze' : '') +
  502. '({' + structure.map(key => key === '__proto__' ? '__proto_:r()' : validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '})}'))(read);
  503. if (structure.highByte === 0)
  504. structure.read = createSecondByteReader(firstId, structure.read);
  505. return readObject() // second byte is already read, if there is one so immediately read object
  506. }
  507. let object = {};
  508. for (let i = 0, l = structure.length; i < l; i++) {
  509. let key = structure[i];
  510. if (key === '__proto__')
  511. key = '__proto_';
  512. object[key] = read();
  513. }
  514. if (currentUnpackr.freezeData)
  515. return Object.freeze(object);
  516. return object
  517. }
  518. readObject.count = 0;
  519. if (structure.highByte === 0) {
  520. return createSecondByteReader(firstId, readObject)
  521. }
  522. return readObject
  523. }
  524. const createSecondByteReader = (firstId, read0) => {
  525. return function() {
  526. let highByte = src[position$1++];
  527. if (highByte === 0)
  528. return read0()
  529. let id = firstId < 32 ? -(firstId + (highByte << 5)) : firstId + (highByte << 5);
  530. let structure = currentStructures[id] || loadStructures()[id];
  531. if (!structure) {
  532. throw new Error('Record id is not defined for ' + id)
  533. }
  534. if (!structure.read)
  535. structure.read = createStructureReader(structure, firstId);
  536. return structure.read()
  537. }
  538. };
  539. function loadStructures() {
  540. let loadedStructures = saveState$1(() => {
  541. // save the state in case getStructures modifies our buffer
  542. src = null;
  543. return currentUnpackr.getStructures()
  544. });
  545. return currentStructures = currentUnpackr._mergeStructures(loadedStructures, currentStructures)
  546. }
  547. var readFixedString = readStringJS;
  548. var readString8 = readStringJS;
  549. var readString16 = readStringJS;
  550. var readString32 = readStringJS;
  551. function setExtractor(extractStrings) {
  552. readFixedString = readString(1);
  553. readString8 = readString(2);
  554. readString16 = readString(3);
  555. readString32 = readString(5);
  556. function readString(headerLength) {
  557. return function readString(length) {
  558. let string = strings[stringPosition++];
  559. if (string == null) {
  560. if (bundledStrings$1)
  561. return readStringJS(length)
  562. let byteOffset = src.byteOffset;
  563. let extraction = extractStrings(position$1 - headerLength + byteOffset, srcEnd + byteOffset, src.buffer);
  564. if (typeof extraction == 'string') {
  565. string = extraction;
  566. strings = EMPTY_ARRAY;
  567. } else {
  568. strings = extraction;
  569. stringPosition = 1;
  570. srcStringEnd = 1; // even if a utf-8 string was decoded, must indicate we are in the midst of extracted strings and can't skip strings
  571. string = strings[0];
  572. if (string === undefined)
  573. throw new Error('Unexpected end of buffer')
  574. }
  575. }
  576. let srcStringLength = string.length;
  577. if (srcStringLength <= length) {
  578. position$1 += length;
  579. return string
  580. }
  581. srcString = string;
  582. srcStringStart = position$1;
  583. srcStringEnd = position$1 + srcStringLength;
  584. position$1 += length;
  585. return string.slice(0, length) // we know we just want the beginning
  586. }
  587. }
  588. }
  589. function readStringJS(length) {
  590. let result;
  591. if (length < 16) {
  592. if (result = shortStringInJS(length))
  593. return result
  594. }
  595. if (length > 64 && decoder)
  596. return decoder.decode(src.subarray(position$1, position$1 += length))
  597. const end = position$1 + length;
  598. const units = [];
  599. result = '';
  600. while (position$1 < end) {
  601. const byte1 = src[position$1++];
  602. if ((byte1 & 0x80) === 0) {
  603. // 1 byte
  604. units.push(byte1);
  605. } else if ((byte1 & 0xe0) === 0xc0) {
  606. // 2 bytes
  607. const byte2 = src[position$1++] & 0x3f;
  608. units.push(((byte1 & 0x1f) << 6) | byte2);
  609. } else if ((byte1 & 0xf0) === 0xe0) {
  610. // 3 bytes
  611. const byte2 = src[position$1++] & 0x3f;
  612. const byte3 = src[position$1++] & 0x3f;
  613. units.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3);
  614. } else if ((byte1 & 0xf8) === 0xf0) {
  615. // 4 bytes
  616. const byte2 = src[position$1++] & 0x3f;
  617. const byte3 = src[position$1++] & 0x3f;
  618. const byte4 = src[position$1++] & 0x3f;
  619. let unit = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
  620. if (unit > 0xffff) {
  621. unit -= 0x10000;
  622. units.push(((unit >>> 10) & 0x3ff) | 0xd800);
  623. unit = 0xdc00 | (unit & 0x3ff);
  624. }
  625. units.push(unit);
  626. } else {
  627. units.push(byte1);
  628. }
  629. if (units.length >= 0x1000) {
  630. result += fromCharCode.apply(String, units);
  631. units.length = 0;
  632. }
  633. }
  634. if (units.length > 0) {
  635. result += fromCharCode.apply(String, units);
  636. }
  637. return result
  638. }
  639. function readString(source, start, length) {
  640. let existingSrc = src;
  641. src = source;
  642. position$1 = start;
  643. try {
  644. return readStringJS(length);
  645. } finally {
  646. src = existingSrc;
  647. }
  648. }
  649. function readArray(length) {
  650. let array = new Array(length);
  651. for (let i = 0; i < length; i++) {
  652. array[i] = read();
  653. }
  654. if (currentUnpackr.freezeData)
  655. return Object.freeze(array)
  656. return array
  657. }
  658. function readMap(length) {
  659. if (currentUnpackr.mapsAsObjects) {
  660. let object = {};
  661. for (let i = 0; i < length; i++) {
  662. let key = readKey();
  663. if (key === '__proto__')
  664. key = '__proto_';
  665. object[key] = read();
  666. }
  667. return object
  668. } else {
  669. let map = new Map();
  670. for (let i = 0; i < length; i++) {
  671. map.set(read(), read());
  672. }
  673. return map
  674. }
  675. }
  676. var fromCharCode = String.fromCharCode;
  677. function longStringInJS(length) {
  678. let start = position$1;
  679. let bytes = new Array(length);
  680. for (let i = 0; i < length; i++) {
  681. const byte = src[position$1++];
  682. if ((byte & 0x80) > 0) {
  683. position$1 = start;
  684. return
  685. }
  686. bytes[i] = byte;
  687. }
  688. return fromCharCode.apply(String, bytes)
  689. }
  690. function shortStringInJS(length) {
  691. if (length < 4) {
  692. if (length < 2) {
  693. if (length === 0)
  694. return ''
  695. else {
  696. let a = src[position$1++];
  697. if ((a & 0x80) > 1) {
  698. position$1 -= 1;
  699. return
  700. }
  701. return fromCharCode(a)
  702. }
  703. } else {
  704. let a = src[position$1++];
  705. let b = src[position$1++];
  706. if ((a & 0x80) > 0 || (b & 0x80) > 0) {
  707. position$1 -= 2;
  708. return
  709. }
  710. if (length < 3)
  711. return fromCharCode(a, b)
  712. let c = src[position$1++];
  713. if ((c & 0x80) > 0) {
  714. position$1 -= 3;
  715. return
  716. }
  717. return fromCharCode(a, b, c)
  718. }
  719. } else {
  720. let a = src[position$1++];
  721. let b = src[position$1++];
  722. let c = src[position$1++];
  723. let d = src[position$1++];
  724. if ((a & 0x80) > 0 || (b & 0x80) > 0 || (c & 0x80) > 0 || (d & 0x80) > 0) {
  725. position$1 -= 4;
  726. return
  727. }
  728. if (length < 6) {
  729. if (length === 4)
  730. return fromCharCode(a, b, c, d)
  731. else {
  732. let e = src[position$1++];
  733. if ((e & 0x80) > 0) {
  734. position$1 -= 5;
  735. return
  736. }
  737. return fromCharCode(a, b, c, d, e)
  738. }
  739. } else if (length < 8) {
  740. let e = src[position$1++];
  741. let f = src[position$1++];
  742. if ((e & 0x80) > 0 || (f & 0x80) > 0) {
  743. position$1 -= 6;
  744. return
  745. }
  746. if (length < 7)
  747. return fromCharCode(a, b, c, d, e, f)
  748. let g = src[position$1++];
  749. if ((g & 0x80) > 0) {
  750. position$1 -= 7;
  751. return
  752. }
  753. return fromCharCode(a, b, c, d, e, f, g)
  754. } else {
  755. let e = src[position$1++];
  756. let f = src[position$1++];
  757. let g = src[position$1++];
  758. let h = src[position$1++];
  759. if ((e & 0x80) > 0 || (f & 0x80) > 0 || (g & 0x80) > 0 || (h & 0x80) > 0) {
  760. position$1 -= 8;
  761. return
  762. }
  763. if (length < 10) {
  764. if (length === 8)
  765. return fromCharCode(a, b, c, d, e, f, g, h)
  766. else {
  767. let i = src[position$1++];
  768. if ((i & 0x80) > 0) {
  769. position$1 -= 9;
  770. return
  771. }
  772. return fromCharCode(a, b, c, d, e, f, g, h, i)
  773. }
  774. } else if (length < 12) {
  775. let i = src[position$1++];
  776. let j = src[position$1++];
  777. if ((i & 0x80) > 0 || (j & 0x80) > 0) {
  778. position$1 -= 10;
  779. return
  780. }
  781. if (length < 11)
  782. return fromCharCode(a, b, c, d, e, f, g, h, i, j)
  783. let k = src[position$1++];
  784. if ((k & 0x80) > 0) {
  785. position$1 -= 11;
  786. return
  787. }
  788. return fromCharCode(a, b, c, d, e, f, g, h, i, j, k)
  789. } else {
  790. let i = src[position$1++];
  791. let j = src[position$1++];
  792. let k = src[position$1++];
  793. let l = src[position$1++];
  794. if ((i & 0x80) > 0 || (j & 0x80) > 0 || (k & 0x80) > 0 || (l & 0x80) > 0) {
  795. position$1 -= 12;
  796. return
  797. }
  798. if (length < 14) {
  799. if (length === 12)
  800. return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l)
  801. else {
  802. let m = src[position$1++];
  803. if ((m & 0x80) > 0) {
  804. position$1 -= 13;
  805. return
  806. }
  807. return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m)
  808. }
  809. } else {
  810. let m = src[position$1++];
  811. let n = src[position$1++];
  812. if ((m & 0x80) > 0 || (n & 0x80) > 0) {
  813. position$1 -= 14;
  814. return
  815. }
  816. if (length < 15)
  817. return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n)
  818. let o = src[position$1++];
  819. if ((o & 0x80) > 0) {
  820. position$1 -= 15;
  821. return
  822. }
  823. return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
  824. }
  825. }
  826. }
  827. }
  828. }
  829. function readOnlyJSString() {
  830. let token = src[position$1++];
  831. let length;
  832. if (token < 0xc0) {
  833. // fixstr
  834. length = token - 0xa0;
  835. } else {
  836. switch(token) {
  837. case 0xd9:
  838. // str 8
  839. length = src[position$1++];
  840. break
  841. case 0xda:
  842. // str 16
  843. length = dataView.getUint16(position$1);
  844. position$1 += 2;
  845. break
  846. case 0xdb:
  847. // str 32
  848. length = dataView.getUint32(position$1);
  849. position$1 += 4;
  850. break
  851. default:
  852. throw new Error('Expected string')
  853. }
  854. }
  855. return readStringJS(length)
  856. }
  857. function readBin(length) {
  858. return currentUnpackr.copyBuffers ?
  859. // specifically use the copying slice (not the node one)
  860. Uint8Array.prototype.slice.call(src, position$1, position$1 += length) :
  861. src.subarray(position$1, position$1 += length)
  862. }
  863. function readExt(length) {
  864. let type = src[position$1++];
  865. if (currentExtensions[type]) {
  866. let end;
  867. return currentExtensions[type](src.subarray(position$1, end = (position$1 += length)), (readPosition) => {
  868. position$1 = readPosition;
  869. try {
  870. return read();
  871. } finally {
  872. position$1 = end;
  873. }
  874. })
  875. }
  876. else
  877. throw new Error('Unknown extension type ' + type)
  878. }
  879. var keyCache = new Array(4096);
  880. function readKey() {
  881. let length = src[position$1++];
  882. if (length >= 0xa0 && length < 0xc0) {
  883. // fixstr, potentially use key cache
  884. length = length - 0xa0;
  885. if (srcStringEnd >= position$1) // if it has been extracted, must use it (and faster anyway)
  886. return srcString.slice(position$1 - srcStringStart, (position$1 += length) - srcStringStart)
  887. else if (!(srcStringEnd == 0 && srcEnd < 180))
  888. return readFixedString(length)
  889. } else { // not cacheable, go back and do a standard read
  890. position$1--;
  891. return asSafeString(read())
  892. }
  893. let key = ((length << 5) ^ (length > 1 ? dataView.getUint16(position$1) : length > 0 ? src[position$1] : 0)) & 0xfff;
  894. let entry = keyCache[key];
  895. let checkPosition = position$1;
  896. let end = position$1 + length - 3;
  897. let chunk;
  898. let i = 0;
  899. if (entry && entry.bytes == length) {
  900. while (checkPosition < end) {
  901. chunk = dataView.getUint32(checkPosition);
  902. if (chunk != entry[i++]) {
  903. checkPosition = 0x70000000;
  904. break
  905. }
  906. checkPosition += 4;
  907. }
  908. end += 3;
  909. while (checkPosition < end) {
  910. chunk = src[checkPosition++];
  911. if (chunk != entry[i++]) {
  912. checkPosition = 0x70000000;
  913. break
  914. }
  915. }
  916. if (checkPosition === end) {
  917. position$1 = checkPosition;
  918. return entry.string
  919. }
  920. end -= 3;
  921. checkPosition = position$1;
  922. }
  923. entry = [];
  924. keyCache[key] = entry;
  925. entry.bytes = length;
  926. while (checkPosition < end) {
  927. chunk = dataView.getUint32(checkPosition);
  928. entry.push(chunk);
  929. checkPosition += 4;
  930. }
  931. end += 3;
  932. while (checkPosition < end) {
  933. chunk = src[checkPosition++];
  934. entry.push(chunk);
  935. }
  936. // for small blocks, avoiding the overhead of the extract call is helpful
  937. let string = length < 16 ? shortStringInJS(length) : longStringInJS(length);
  938. if (string != null)
  939. return entry.string = string
  940. return entry.string = readFixedString(length)
  941. }
  942. function asSafeString(property) {
  943. // protect against expensive (DoS) string conversions
  944. if (typeof property === 'string') return property;
  945. if (typeof property === 'number' || typeof property === 'boolean' || typeof property === 'bigint') return property.toString();
  946. if (property == null) return property + '';
  947. throw new Error('Invalid property type for record', typeof property);
  948. }
  949. // the registration of the record definition extension (as "r")
  950. const recordDefinition = (id, highByte) => {
  951. let structure = read().map(asSafeString); // ensure that all keys are strings and
  952. // that the array is mutable
  953. let firstByte = id;
  954. if (highByte !== undefined) {
  955. id = id < 32 ? -((highByte << 5) + id) : ((highByte << 5) + id);
  956. structure.highByte = highByte;
  957. }
  958. let existingStructure = currentStructures[id];
  959. // If it is a shared structure, we need to restore any changes after reading.
  960. // Also in sequential mode, we may get incomplete reads and thus errors, and we need to restore
  961. // to the state prior to an incomplete read in order to properly resume.
  962. if (existingStructure && (existingStructure.isShared || sequentialMode)) {
  963. (currentStructures.restoreStructures || (currentStructures.restoreStructures = []))[id] = existingStructure;
  964. }
  965. currentStructures[id] = structure;
  966. structure.read = createStructureReader(structure, firstByte);
  967. return structure.read()
  968. };
  969. currentExtensions[0] = () => {}; // notepack defines extension 0 to mean undefined, so use that as the default here
  970. currentExtensions[0].noBuffer = true;
  971. currentExtensions[0x42] = (data) => {
  972. // decode bigint
  973. let length = data.length;
  974. let value = BigInt(data[0] & 0x80 ? data[0] - 0x100 : data[0]);
  975. for (let i = 1; i < length; i++) {
  976. value <<= BigInt(8);
  977. value += BigInt(data[i]);
  978. }
  979. return value;
  980. };
  981. let errors = { Error, TypeError, ReferenceError };
  982. currentExtensions[0x65] = () => {
  983. let data = read();
  984. return (errors[data[0]] || Error)(data[1], { cause: data[2] })
  985. };
  986. currentExtensions[0x69] = (data) => {
  987. // id extension (for structured clones)
  988. if (currentUnpackr.structuredClone === false) throw new Error('Structured clone extension is disabled')
  989. let id = dataView.getUint32(position$1 - 4);
  990. if (!referenceMap)
  991. referenceMap = new Map();
  992. let token = src[position$1];
  993. let target;
  994. // TODO: handle Maps, Sets, and other types that can cycle; this is complicated, because you potentially need to read
  995. // ahead past references to record structure definitions
  996. if (token >= 0x90 && token < 0xa0 || token == 0xdc || token == 0xdd)
  997. target = [];
  998. else
  999. target = {};
  1000. let refEntry = { target }; // a placeholder object
  1001. referenceMap.set(id, refEntry);
  1002. let targetProperties = read(); // read the next value as the target object to id
  1003. if (refEntry.used) // there is a cycle, so we have to assign properties to original target
  1004. return Object.assign(target, targetProperties)
  1005. refEntry.target = targetProperties; // the placeholder wasn't used, replace with the deserialized one
  1006. return targetProperties // no cycle, can just use the returned read object
  1007. };
  1008. currentExtensions[0x70] = (data) => {
  1009. // pointer extension (for structured clones)
  1010. if (currentUnpackr.structuredClone === false) throw new Error('Structured clone extension is disabled')
  1011. let id = dataView.getUint32(position$1 - 4);
  1012. let refEntry = referenceMap.get(id);
  1013. refEntry.used = true;
  1014. return refEntry.target
  1015. };
  1016. currentExtensions[0x73] = () => new Set(read());
  1017. const typedArrays = ['Int8','Uint8','Uint8Clamped','Int16','Uint16','Int32','Uint32','Float32','Float64','BigInt64','BigUint64'].map(type => type + 'Array');
  1018. let glbl = typeof globalThis === 'object' ? globalThis : window;
  1019. currentExtensions[0x74] = (data) => {
  1020. let typeCode = data[0];
  1021. let typedArrayName = typedArrays[typeCode];
  1022. if (!typedArrayName) {
  1023. if (typeCode === 16) {
  1024. let ab = new ArrayBuffer(data.length - 1);
  1025. let u8 = new Uint8Array(ab);
  1026. u8.set(data.subarray(1));
  1027. return ab;
  1028. }
  1029. throw new Error('Could not find typed array for code ' + typeCode)
  1030. }
  1031. // we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned
  1032. return new glbl[typedArrayName](Uint8Array.prototype.slice.call(data, 1).buffer)
  1033. };
  1034. currentExtensions[0x78] = () => {
  1035. let data = read();
  1036. return new RegExp(data[0], data[1])
  1037. };
  1038. const TEMP_BUNDLE = [];
  1039. currentExtensions[0x62] = (data) => {
  1040. let dataSize = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
  1041. let dataPosition = position$1;
  1042. position$1 += dataSize - data.length;
  1043. bundledStrings$1 = TEMP_BUNDLE;
  1044. bundledStrings$1 = [readOnlyJSString(), readOnlyJSString()];
  1045. bundledStrings$1.position0 = 0;
  1046. bundledStrings$1.position1 = 0;
  1047. bundledStrings$1.postBundlePosition = position$1;
  1048. position$1 = dataPosition;
  1049. return read()
  1050. };
  1051. currentExtensions[0xff] = (data) => {
  1052. // 32-bit date extension
  1053. if (data.length == 4)
  1054. return new Date((data[0] * 0x1000000 + (data[1] << 16) + (data[2] << 8) + data[3]) * 1000)
  1055. else if (data.length == 8)
  1056. return new Date(
  1057. ((data[0] << 22) + (data[1] << 14) + (data[2] << 6) + (data[3] >> 2)) / 1000000 +
  1058. ((data[3] & 0x3) * 0x100000000 + data[4] * 0x1000000 + (data[5] << 16) + (data[6] << 8) + data[7]) * 1000)
  1059. else if (data.length == 12)// TODO: Implement support for negative
  1060. return new Date(
  1061. ((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]) / 1000000 +
  1062. (((data[4] & 0x80) ? -0x1000000000000 : 0) + data[6] * 0x10000000000 + data[7] * 0x100000000 + data[8] * 0x1000000 + (data[9] << 16) + (data[10] << 8) + data[11]) * 1000)
  1063. else
  1064. return new Date('invalid')
  1065. }; // notepack defines extension 0 to mean undefined, so use that as the default here
  1066. // registration of bulk record definition?
  1067. // currentExtensions[0x52] = () =>
  1068. function saveState$1(callback) {
  1069. if (onSaveState)
  1070. onSaveState();
  1071. let savedSrcEnd = srcEnd;
  1072. let savedPosition = position$1;
  1073. let savedStringPosition = stringPosition;
  1074. let savedSrcStringStart = srcStringStart;
  1075. let savedSrcStringEnd = srcStringEnd;
  1076. let savedSrcString = srcString;
  1077. let savedStrings = strings;
  1078. let savedReferenceMap = referenceMap;
  1079. let savedBundledStrings = bundledStrings$1;
  1080. // TODO: We may need to revisit this if we do more external calls to user code (since it could be slow)
  1081. let savedSrc = new Uint8Array(src.slice(0, srcEnd)); // we copy the data in case it changes while external data is processed
  1082. let savedStructures = currentStructures;
  1083. let savedStructuresContents = currentStructures.slice(0, currentStructures.length);
  1084. let savedPackr = currentUnpackr;
  1085. let savedSequentialMode = sequentialMode;
  1086. let value = callback();
  1087. srcEnd = savedSrcEnd;
  1088. position$1 = savedPosition;
  1089. stringPosition = savedStringPosition;
  1090. srcStringStart = savedSrcStringStart;
  1091. srcStringEnd = savedSrcStringEnd;
  1092. srcString = savedSrcString;
  1093. strings = savedStrings;
  1094. referenceMap = savedReferenceMap;
  1095. bundledStrings$1 = savedBundledStrings;
  1096. src = savedSrc;
  1097. sequentialMode = savedSequentialMode;
  1098. currentStructures = savedStructures;
  1099. currentStructures.splice(0, currentStructures.length, ...savedStructuresContents);
  1100. currentUnpackr = savedPackr;
  1101. dataView = new DataView(src.buffer, src.byteOffset, src.byteLength);
  1102. return value
  1103. }
  1104. function clearSource() {
  1105. src = null;
  1106. referenceMap = null;
  1107. currentStructures = null;
  1108. }
  1109. function addExtension$2(extension) {
  1110. if (extension.unpack)
  1111. currentExtensions[extension.type] = extension.unpack;
  1112. else
  1113. currentExtensions[extension.type] = extension;
  1114. }
  1115. const mult10 = new Array(147); // this is a table matching binary exponents to the multiplier to determine significant digit rounding
  1116. for (let i = 0; i < 256; i++) {
  1117. mult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103));
  1118. }
  1119. var defaultUnpackr = new Unpackr$1({ useRecords: false });
  1120. const unpack$1 = defaultUnpackr.unpack;
  1121. const unpackMultiple$1 = defaultUnpackr.unpackMultiple;
  1122. defaultUnpackr.unpack;
  1123. const FLOAT32_OPTIONS = {
  1124. NEVER: 0,
  1125. ALWAYS: 1,
  1126. DECIMAL_ROUND: 3,
  1127. DECIMAL_FIT: 4
  1128. };
  1129. let f32Array = new Float32Array(1);
  1130. let u8Array = new Uint8Array(f32Array.buffer, 0, 4);
  1131. function roundFloat32$1(float32Number) {
  1132. f32Array[0] = float32Number;
  1133. let multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)];
  1134. return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier
  1135. }
  1136. function setReadStruct(updatedReadStruct, loadedStructs, saveState) {
  1137. readStruct$1 = updatedReadStruct;
  1138. onLoadedStructures$1 = loadedStructs;
  1139. onSaveState = saveState;
  1140. }
  1141. let textEncoder$1;
  1142. try {
  1143. textEncoder$1 = new TextEncoder();
  1144. } catch (error) {}
  1145. let extensions, extensionClasses;
  1146. const hasNodeBuffer$1 = typeof Buffer !== 'undefined';
  1147. const ByteArrayAllocate = hasNodeBuffer$1 ?
  1148. function(length) { return Buffer.allocUnsafeSlow(length) } : Uint8Array;
  1149. const ByteArray = hasNodeBuffer$1 ? Buffer : Uint8Array;
  1150. const MAX_BUFFER_SIZE = hasNodeBuffer$1 ? 0x100000000 : 0x7fd00000;
  1151. let target, keysTarget;
  1152. let targetView;
  1153. let position = 0;
  1154. let safeEnd;
  1155. let bundledStrings = null;
  1156. let writeStructSlots;
  1157. const MAX_BUNDLE_SIZE = 0x5500; // maximum characters such that the encoded bytes fits in 16 bits.
  1158. const hasNonLatin = /[\u0080-\uFFFF]/;
  1159. const RECORD_SYMBOL = Symbol('record-id');
  1160. let Packr$1 = class Packr extends Unpackr$1 {
  1161. constructor(options) {
  1162. super(options);
  1163. this.offset = 0;
  1164. let start;
  1165. let hasSharedUpdate;
  1166. let structures;
  1167. let referenceMap;
  1168. let encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position) {
  1169. return target.utf8Write(string, position, target.byteLength - position)
  1170. } : (textEncoder$1 && textEncoder$1.encodeInto) ?
  1171. function(string, position) {
  1172. return textEncoder$1.encodeInto(string, target.subarray(position)).written
  1173. } : false;
  1174. let packr = this;
  1175. if (!options)
  1176. options = {};
  1177. let isSequential = options && options.sequential;
  1178. let hasSharedStructures = options.structures || options.saveStructures;
  1179. let maxSharedStructures = options.maxSharedStructures;
  1180. if (maxSharedStructures == null)
  1181. maxSharedStructures = hasSharedStructures ? 32 : 0;
  1182. if (maxSharedStructures > 8160)
  1183. throw new Error('Maximum maxSharedStructure is 8160')
  1184. if (options.structuredClone && options.moreTypes == undefined) {
  1185. this.moreTypes = true;
  1186. }
  1187. let maxOwnStructures = options.maxOwnStructures;
  1188. if (maxOwnStructures == null)
  1189. maxOwnStructures = hasSharedStructures ? 32 : 64;
  1190. if (!this.structures && options.useRecords != false)
  1191. this.structures = [];
  1192. // two byte record ids for shared structures
  1193. let useTwoByteRecords = maxSharedStructures > 32 || (maxOwnStructures + maxSharedStructures > 64);
  1194. let sharedLimitId = maxSharedStructures + 0x40;
  1195. let maxStructureId = maxSharedStructures + maxOwnStructures + 0x40;
  1196. if (maxStructureId > 8256) {
  1197. throw new Error('Maximum maxSharedStructure + maxOwnStructure is 8192')
  1198. }
  1199. let recordIdsToRemove = [];
  1200. let transitionsCount = 0;
  1201. let serializationsSinceTransitionRebuild = 0;
  1202. this.pack = this.encode = function(value, encodeOptions) {
  1203. if (!target) {
  1204. target = new ByteArrayAllocate(8192);
  1205. targetView = target.dataView || (target.dataView = new DataView(target.buffer, 0, 8192));
  1206. position = 0;
  1207. }
  1208. safeEnd = target.length - 10;
  1209. if (safeEnd - position < 0x800) {
  1210. // don't start too close to the end,
  1211. target = new ByteArrayAllocate(target.length);
  1212. targetView = target.dataView || (target.dataView = new DataView(target.buffer, 0, target.length));
  1213. safeEnd = target.length - 10;
  1214. position = 0;
  1215. } else
  1216. position = (position + 7) & 0x7ffffff8; // Word align to make any future copying of this buffer faster
  1217. start = position;
  1218. if (encodeOptions & RESERVE_START_SPACE) position += (encodeOptions & 0xff);
  1219. referenceMap = packr.structuredClone ? new Map() : null;
  1220. if (packr.bundleStrings && typeof value !== 'string') {
  1221. bundledStrings = [];
  1222. bundledStrings.size = Infinity; // force a new bundle start on first string
  1223. } else
  1224. bundledStrings = null;
  1225. structures = packr.structures;
  1226. if (structures) {
  1227. if (structures.uninitialized)
  1228. structures = packr._mergeStructures(packr.getStructures());
  1229. let sharedLength = structures.sharedLength || 0;
  1230. if (sharedLength > maxSharedStructures) {
  1231. //if (maxSharedStructures <= 32 && structures.sharedLength > 32) // TODO: could support this, but would need to update the limit ids
  1232. throw new Error('Shared structures is larger than maximum shared structures, try increasing maxSharedStructures to ' + structures.sharedLength)
  1233. }
  1234. if (!structures.transitions) {
  1235. // rebuild our structure transitions
  1236. structures.transitions = Object.create(null);
  1237. for (let i = 0; i < sharedLength; i++) {
  1238. let keys = structures[i];
  1239. if (!keys)
  1240. continue
  1241. let nextTransition, transition = structures.transitions;
  1242. for (let j = 0, l = keys.length; j < l; j++) {
  1243. let key = keys[j];
  1244. nextTransition = transition[key];
  1245. if (!nextTransition) {
  1246. nextTransition = transition[key] = Object.create(null);
  1247. }
  1248. transition = nextTransition;
  1249. }
  1250. transition[RECORD_SYMBOL] = i + 0x40;
  1251. }
  1252. this.lastNamedStructuresLength = sharedLength;
  1253. }
  1254. if (!isSequential) {
  1255. structures.nextId = sharedLength + 0x40;
  1256. }
  1257. }
  1258. if (hasSharedUpdate)
  1259. hasSharedUpdate = false;
  1260. let encodingError;
  1261. try {
  1262. if (packr.randomAccessStructure && value && value.constructor && value.constructor === Object)
  1263. writeStruct(value);
  1264. else
  1265. pack(value);
  1266. let lastBundle = bundledStrings;
  1267. if (bundledStrings)
  1268. writeBundles(start, pack, 0);
  1269. if (referenceMap && referenceMap.idsToInsert) {
  1270. let idsToInsert = referenceMap.idsToInsert.sort((a, b) => a.offset > b.offset ? 1 : -1);
  1271. let i = idsToInsert.length;
  1272. let incrementPosition = -1;
  1273. while (lastBundle && i > 0) {
  1274. let insertionPoint = idsToInsert[--i].offset + start;
  1275. if (insertionPoint < (lastBundle.stringsPosition + start) && incrementPosition === -1)
  1276. incrementPosition = 0;
  1277. if (insertionPoint > (lastBundle.position + start)) {
  1278. if (incrementPosition >= 0)
  1279. incrementPosition += 6;
  1280. } else {
  1281. if (incrementPosition >= 0) {
  1282. // update the bundle reference now
  1283. targetView.setUint32(lastBundle.position + start,
  1284. targetView.getUint32(lastBundle.position + start) + incrementPosition);
  1285. incrementPosition = -1; // reset
  1286. }
  1287. lastBundle = lastBundle.previous;
  1288. i++;
  1289. }
  1290. }
  1291. if (incrementPosition >= 0 && lastBundle) {
  1292. // update the bundle reference now
  1293. targetView.setUint32(lastBundle.position + start,
  1294. targetView.getUint32(lastBundle.position + start) + incrementPosition);
  1295. }
  1296. position += idsToInsert.length * 6;
  1297. if (position > safeEnd)
  1298. makeRoom(position);
  1299. packr.offset = position;
  1300. let serialized = insertIds(target.subarray(start, position), idsToInsert);
  1301. referenceMap = null;
  1302. return serialized
  1303. }
  1304. packr.offset = position; // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
  1305. if (encodeOptions & REUSE_BUFFER_MODE) {
  1306. target.start = start;
  1307. target.end = position;
  1308. return target
  1309. }
  1310. return target.subarray(start, position) // position can change if we call pack again in saveStructures, so we get the buffer now
  1311. } catch(error) {
  1312. encodingError = error;
  1313. throw error;
  1314. } finally {
  1315. if (structures) {
  1316. resetStructures();
  1317. if (hasSharedUpdate && packr.saveStructures) {
  1318. let sharedLength = structures.sharedLength || 0;
  1319. // we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
  1320. let returnBuffer = target.subarray(start, position);
  1321. let newSharedData = prepareStructures$1(structures, packr);
  1322. if (!encodingError) { // TODO: If there is an encoding error, should make the structures as uninitialized so they get rebuilt next time
  1323. if (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
  1324. // get updated structures and try again if the update failed
  1325. return packr.pack(value, encodeOptions)
  1326. }
  1327. packr.lastNamedStructuresLength = sharedLength;
  1328. // don't keep large buffers around
  1329. if (target.length > 0x40000000) target = null;
  1330. return returnBuffer
  1331. }
  1332. }
  1333. }
  1334. // don't keep large buffers around, they take too much memory and cause problems (limit at 1GB)
  1335. if (target.length > 0x40000000) target = null;
  1336. if (encodeOptions & RESET_BUFFER_MODE)
  1337. position = start;
  1338. }
  1339. };
  1340. const resetStructures = () => {
  1341. if (serializationsSinceTransitionRebuild < 10)
  1342. serializationsSinceTransitionRebuild++;
  1343. let sharedLength = structures.sharedLength || 0;
  1344. if (structures.length > sharedLength && !isSequential)
  1345. structures.length = sharedLength;
  1346. if (transitionsCount > 10000) {
  1347. // force a rebuild occasionally after a lot of transitions so it can get cleaned up
  1348. structures.transitions = null;
  1349. serializationsSinceTransitionRebuild = 0;
  1350. transitionsCount = 0;
  1351. if (recordIdsToRemove.length > 0)
  1352. recordIdsToRemove = [];
  1353. } else if (recordIdsToRemove.length > 0 && !isSequential) {
  1354. for (let i = 0, l = recordIdsToRemove.length; i < l; i++) {
  1355. recordIdsToRemove[i][RECORD_SYMBOL] = 0;
  1356. }
  1357. recordIdsToRemove = [];
  1358. }
  1359. };
  1360. const packArray = (value) => {
  1361. var length = value.length;
  1362. if (length < 0x10) {
  1363. target[position++] = 0x90 | length;
  1364. } else if (length < 0x10000) {
  1365. target[position++] = 0xdc;
  1366. target[position++] = length >> 8;
  1367. target[position++] = length & 0xff;
  1368. } else {
  1369. target[position++] = 0xdd;
  1370. targetView.setUint32(position, length);
  1371. position += 4;
  1372. }
  1373. for (let i = 0; i < length; i++) {
  1374. pack(value[i]);
  1375. }
  1376. };
  1377. const pack = (value) => {
  1378. if (position > safeEnd)
  1379. target = makeRoom(position);
  1380. var type = typeof value;
  1381. var length;
  1382. if (type === 'string') {
  1383. let strLength = value.length;
  1384. if (bundledStrings && strLength >= 4 && strLength < 0x1000) {
  1385. if ((bundledStrings.size += strLength) > MAX_BUNDLE_SIZE) {
  1386. let extStart;
  1387. let maxBytes = (bundledStrings[0] ? bundledStrings[0].length * 3 + bundledStrings[1].length : 0) + 10;
  1388. if (position + maxBytes > safeEnd)
  1389. target = makeRoom(position + maxBytes);
  1390. let lastBundle;
  1391. 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
  1392. lastBundle = bundledStrings;
  1393. target[position] = 0xc8; // ext 16
  1394. position += 3; // reserve for the writing bundle size
  1395. target[position++] = 0x62; // 'b'
  1396. extStart = position - start;
  1397. position += 4; // reserve for writing bundle reference
  1398. writeBundles(start, pack, 0); // write the last bundles
  1399. targetView.setUint16(extStart + start - 3, position - start - extStart);
  1400. } 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)
  1401. target[position++] = 0xd6; // fixext 4
  1402. target[position++] = 0x62; // 'b'
  1403. extStart = position - start;
  1404. position += 4; // reserve for writing bundle reference
  1405. }
  1406. bundledStrings = ['', '']; // create new ones
  1407. bundledStrings.previous = lastBundle;
  1408. bundledStrings.size = 0;
  1409. bundledStrings.position = extStart;
  1410. }
  1411. let twoByte = hasNonLatin.test(value);
  1412. bundledStrings[twoByte ? 0 : 1] += value;
  1413. target[position++] = 0xc1;
  1414. pack(twoByte ? -strLength : strLength);
  1415. return
  1416. }
  1417. let headerSize;
  1418. // first we estimate the header size, so we can write to the correct location
  1419. if (strLength < 0x20) {
  1420. headerSize = 1;
  1421. } else if (strLength < 0x100) {
  1422. headerSize = 2;
  1423. } else if (strLength < 0x10000) {
  1424. headerSize = 3;
  1425. } else {
  1426. headerSize = 5;
  1427. }
  1428. let maxBytes = strLength * 3;
  1429. if (position + maxBytes > safeEnd)
  1430. target = makeRoom(position + maxBytes);
  1431. if (strLength < 0x40 || !encodeUtf8) {
  1432. let i, c1, c2, strPosition = position + headerSize;
  1433. for (i = 0; i < strLength; i++) {
  1434. c1 = value.charCodeAt(i);
  1435. if (c1 < 0x80) {
  1436. target[strPosition++] = c1;
  1437. } else if (c1 < 0x800) {
  1438. target[strPosition++] = c1 >> 6 | 0xc0;
  1439. target[strPosition++] = c1 & 0x3f | 0x80;
  1440. } else if (
  1441. (c1 & 0xfc00) === 0xd800 &&
  1442. ((c2 = value.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
  1443. ) {
  1444. c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff);
  1445. i++;
  1446. target[strPosition++] = c1 >> 18 | 0xf0;
  1447. target[strPosition++] = c1 >> 12 & 0x3f | 0x80;
  1448. target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
  1449. target[strPosition++] = c1 & 0x3f | 0x80;
  1450. } else {
  1451. target[strPosition++] = c1 >> 12 | 0xe0;
  1452. target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
  1453. target[strPosition++] = c1 & 0x3f | 0x80;
  1454. }
  1455. }
  1456. length = strPosition - position - headerSize;
  1457. } else {
  1458. length = encodeUtf8(value, position + headerSize);
  1459. }
  1460. if (length < 0x20) {
  1461. target[position++] = 0xa0 | length;
  1462. } else if (length < 0x100) {
  1463. if (headerSize < 2) {
  1464. target.copyWithin(position + 2, position + 1, position + 1 + length);
  1465. }
  1466. target[position++] = 0xd9;
  1467. target[position++] = length;
  1468. } else if (length < 0x10000) {
  1469. if (headerSize < 3) {
  1470. target.copyWithin(position + 3, position + 2, position + 2 + length);
  1471. }
  1472. target[position++] = 0xda;
  1473. target[position++] = length >> 8;
  1474. target[position++] = length & 0xff;
  1475. } else {
  1476. if (headerSize < 5) {
  1477. target.copyWithin(position + 5, position + 3, position + 3 + length);
  1478. }
  1479. target[position++] = 0xdb;
  1480. targetView.setUint32(position, length);
  1481. position += 4;
  1482. }
  1483. position += length;
  1484. } else if (type === 'number') {
  1485. if (value >>> 0 === value) {// positive integer, 32-bit or less
  1486. // positive uint
  1487. if (value < 0x20 || (value < 0x80 && this.useRecords === false) || (value < 0x40 && !this.randomAccessStructure)) {
  1488. target[position++] = value;
  1489. } else if (value < 0x100) {
  1490. target[position++] = 0xcc;
  1491. target[position++] = value;
  1492. } else if (value < 0x10000) {
  1493. target[position++] = 0xcd;
  1494. target[position++] = value >> 8;
  1495. target[position++] = value & 0xff;
  1496. } else {
  1497. target[position++] = 0xce;
  1498. targetView.setUint32(position, value);
  1499. position += 4;
  1500. }
  1501. } else if (value >> 0 === value) { // negative integer
  1502. if (value >= -0x20) {
  1503. target[position++] = 0x100 + value;
  1504. } else if (value >= -0x80) {
  1505. target[position++] = 0xd0;
  1506. target[position++] = value + 0x100;
  1507. } else if (value >= -0x8000) {
  1508. target[position++] = 0xd1;
  1509. targetView.setInt16(position, value);
  1510. position += 2;
  1511. } else {
  1512. target[position++] = 0xd2;
  1513. targetView.setInt32(position, value);
  1514. position += 4;
  1515. }
  1516. } else {
  1517. let useFloat32;
  1518. if ((useFloat32 = this.useFloat32) > 0 && value < 0x100000000 && value >= -0x80000000) {
  1519. target[position++] = 0xca;
  1520. targetView.setFloat32(position, value);
  1521. let xShifted;
  1522. if (useFloat32 < 4 ||
  1523. // this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
  1524. ((xShifted = value * mult10[((target[position] & 0x7f) << 1) | (target[position + 1] >> 7)]) >> 0) === xShifted) {
  1525. position += 4;
  1526. return
  1527. } else
  1528. position--; // move back into position for writing a double
  1529. }
  1530. target[position++] = 0xcb;
  1531. targetView.setFloat64(position, value);
  1532. position += 8;
  1533. }
  1534. } else if (type === 'object' || type === 'function') {
  1535. if (!value)
  1536. target[position++] = 0xc0;
  1537. else {
  1538. if (referenceMap) {
  1539. let referee = referenceMap.get(value);
  1540. if (referee) {
  1541. if (!referee.id) {
  1542. let idsToInsert = referenceMap.idsToInsert || (referenceMap.idsToInsert = []);
  1543. referee.id = idsToInsert.push(referee);
  1544. }
  1545. target[position++] = 0xd6; // fixext 4
  1546. target[position++] = 0x70; // "p" for pointer
  1547. targetView.setUint32(position, referee.id);
  1548. position += 4;
  1549. return
  1550. } else
  1551. referenceMap.set(value, { offset: position - start });
  1552. }
  1553. let constructor = value.constructor;
  1554. if (constructor === Object) {
  1555. writeObject(value);
  1556. } else if (constructor === Array) {
  1557. packArray(value);
  1558. } else if (constructor === Map) {
  1559. if (this.mapAsEmptyObject) target[position++] = 0x80;
  1560. else {
  1561. length = value.size;
  1562. if (length < 0x10) {
  1563. target[position++] = 0x80 | length;
  1564. } else if (length < 0x10000) {
  1565. target[position++] = 0xde;
  1566. target[position++] = length >> 8;
  1567. target[position++] = length & 0xff;
  1568. } else {
  1569. target[position++] = 0xdf;
  1570. targetView.setUint32(position, length);
  1571. position += 4;
  1572. }
  1573. for (let [key, entryValue] of value) {
  1574. pack(key);
  1575. pack(entryValue);
  1576. }
  1577. }
  1578. } else {
  1579. for (let i = 0, l = extensions.length; i < l; i++) {
  1580. let extensionClass = extensionClasses[i];
  1581. if (value instanceof extensionClass) {
  1582. let extension = extensions[i];
  1583. if (extension.write) {
  1584. if (extension.type) {
  1585. target[position++] = 0xd4; // one byte "tag" extension
  1586. target[position++] = extension.type;
  1587. target[position++] = 0;
  1588. }
  1589. let writeResult = extension.write.call(this, value);
  1590. if (writeResult === value) { // avoid infinite recursion
  1591. if (Array.isArray(value)) {
  1592. packArray(value);
  1593. } else {
  1594. writeObject(value);
  1595. }
  1596. } else {
  1597. pack(writeResult);
  1598. }
  1599. return
  1600. }
  1601. let currentTarget = target;
  1602. let currentTargetView = targetView;
  1603. let currentPosition = position;
  1604. target = null;
  1605. let result;
  1606. try {
  1607. result = extension.pack.call(this, value, (size) => {
  1608. // restore target and use it
  1609. target = currentTarget;
  1610. currentTarget = null;
  1611. position += size;
  1612. if (position > safeEnd)
  1613. makeRoom(position);
  1614. return {
  1615. target, targetView, position: position - size
  1616. }
  1617. }, pack);
  1618. } finally {
  1619. // restore current target information (unless already restored)
  1620. if (currentTarget) {
  1621. target = currentTarget;
  1622. targetView = currentTargetView;
  1623. position = currentPosition;
  1624. safeEnd = target.length - 10;
  1625. }
  1626. }
  1627. if (result) {
  1628. if (result.length + position > safeEnd)
  1629. makeRoom(result.length + position);
  1630. position = writeExtensionData(result, target, position, extension.type);
  1631. }
  1632. return
  1633. }
  1634. }
  1635. // check isArray after extensions, because extensions can extend Array
  1636. if (Array.isArray(value)) {
  1637. packArray(value);
  1638. } else {
  1639. // use this as an alternate mechanism for expressing how to serialize
  1640. if (value.toJSON) {
  1641. const json = value.toJSON();
  1642. // if for some reason value.toJSON returns itself it'll loop forever
  1643. if (json !== value)
  1644. return pack(json)
  1645. }
  1646. // if there is a writeFunction, use it, otherwise just encode as undefined
  1647. if (type === 'function')
  1648. return pack(this.writeFunction && this.writeFunction(value));
  1649. // no extension found, write as plain object
  1650. writeObject(value);
  1651. }
  1652. }
  1653. }
  1654. } else if (type === 'boolean') {
  1655. target[position++] = value ? 0xc3 : 0xc2;
  1656. } else if (type === 'bigint') {
  1657. if (value < (BigInt(1)<<BigInt(63)) && value >= -(BigInt(1)<<BigInt(63))) {
  1658. // use a signed int as long as it fits
  1659. target[position++] = 0xd3;
  1660. targetView.setBigInt64(position, value);
  1661. } else if (value < (BigInt(1)<<BigInt(64)) && value > 0) {
  1662. // if we can fit an unsigned int, use that
  1663. target[position++] = 0xcf;
  1664. targetView.setBigUint64(position, value);
  1665. } else {
  1666. // overflow
  1667. if (this.largeBigIntToFloat) {
  1668. target[position++] = 0xcb;
  1669. targetView.setFloat64(position, Number(value));
  1670. } else if (this.largeBigIntToString) {
  1671. return pack(value.toString());
  1672. } else if (this.useBigIntExtension && value < BigInt(2)**BigInt(1023) && value > -(BigInt(2)**BigInt(1023))) {
  1673. target[position++] = 0xc7;
  1674. position++;
  1675. target[position++] = 0x42; // "B" for BigInt
  1676. let bytes = [];
  1677. let alignedSign;
  1678. do {
  1679. let byte = value & BigInt(0xff);
  1680. alignedSign = (byte & BigInt(0x80)) === (value < BigInt(0) ? BigInt(0x80) : BigInt(0));
  1681. bytes.push(byte);
  1682. value >>= BigInt(8);
  1683. } while (!((value === BigInt(0) || value === BigInt(-1)) && alignedSign));
  1684. target[position-2] = bytes.length;
  1685. for (let i = bytes.length; i > 0;) {
  1686. target[position++] = Number(bytes[--i]);
  1687. }
  1688. return
  1689. } else {
  1690. throw new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format, use' +
  1691. ' useBigIntExtension, or set largeBigIntToFloat to convert to float-64, or set' +
  1692. ' largeBigIntToString to convert to string')
  1693. }
  1694. }
  1695. position += 8;
  1696. } else if (type === 'undefined') {
  1697. if (this.encodeUndefinedAsNil)
  1698. target[position++] = 0xc0;
  1699. else {
  1700. target[position++] = 0xd4; // a number of implementations use fixext1 with type 0, data 0 to denote undefined, so we follow suite
  1701. target[position++] = 0;
  1702. target[position++] = 0;
  1703. }
  1704. } else {
  1705. throw new Error('Unknown type: ' + type)
  1706. }
  1707. };
  1708. const writePlainObject = (this.variableMapSize || this.coercibleKeyAsNumber || this.skipValues) ? (object) => {
  1709. // this method is slightly slower, but generates "preferred serialization" (optimally small for smaller objects)
  1710. let keys;
  1711. if (this.skipValues) {
  1712. keys = [];
  1713. for (let key in object) {
  1714. if ((typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) &&
  1715. !this.skipValues.includes(object[key]))
  1716. keys.push(key);
  1717. }
  1718. } else {
  1719. keys = Object.keys(object);
  1720. }
  1721. let length = keys.length;
  1722. if (length < 0x10) {
  1723. target[position++] = 0x80 | length;
  1724. } else if (length < 0x10000) {
  1725. target[position++] = 0xde;
  1726. target[position++] = length >> 8;
  1727. target[position++] = length & 0xff;
  1728. } else {
  1729. target[position++] = 0xdf;
  1730. targetView.setUint32(position, length);
  1731. position += 4;
  1732. }
  1733. let key;
  1734. if (this.coercibleKeyAsNumber) {
  1735. for (let i = 0; i < length; i++) {
  1736. key = keys[i];
  1737. let num = Number(key);
  1738. pack(isNaN(num) ? key : num);
  1739. pack(object[key]);
  1740. }
  1741. } else {
  1742. for (let i = 0; i < length; i++) {
  1743. pack(key = keys[i]);
  1744. pack(object[key]);
  1745. }
  1746. }
  1747. } :
  1748. (object) => {
  1749. target[position++] = 0xde; // always using map 16, so we can preallocate and set the length afterwards
  1750. let objectOffset = position - start;
  1751. position += 2;
  1752. let size = 0;
  1753. for (let key in object) {
  1754. if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
  1755. pack(key);
  1756. pack(object[key]);
  1757. size++;
  1758. }
  1759. }
  1760. if (size > 0xffff) {
  1761. throw new Error('Object is too large to serialize with fast 16-bit map size,' +
  1762. ' use the "variableMapSize" option to serialize this object');
  1763. }
  1764. target[objectOffset++ + start] = size >> 8;
  1765. target[objectOffset + start] = size & 0xff;
  1766. };
  1767. const writeRecord = this.useRecords === false ? writePlainObject :
  1768. (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)
  1769. (object) => {
  1770. let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
  1771. let objectOffset = position++ - start;
  1772. let wroteKeys;
  1773. for (let key in object) {
  1774. if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
  1775. nextTransition = transition[key];
  1776. if (nextTransition)
  1777. transition = nextTransition;
  1778. else {
  1779. // record doesn't exist, create full new record and insert it
  1780. let keys = Object.keys(object);
  1781. let lastTransition = transition;
  1782. transition = structures.transitions;
  1783. let newTransitions = 0;
  1784. for (let i = 0, l = keys.length; i < l; i++) {
  1785. let key = keys[i];
  1786. nextTransition = transition[key];
  1787. if (!nextTransition) {
  1788. nextTransition = transition[key] = Object.create(null);
  1789. newTransitions++;
  1790. }
  1791. transition = nextTransition;
  1792. }
  1793. if (objectOffset + start + 1 == position) {
  1794. // first key, so we don't need to insert, we can just write record directly
  1795. position--;
  1796. newRecord(transition, keys, newTransitions);
  1797. } else // otherwise we need to insert the record, moving existing data after the record
  1798. insertNewRecord(transition, keys, objectOffset, newTransitions);
  1799. wroteKeys = true;
  1800. transition = lastTransition[key];
  1801. }
  1802. pack(object[key]);
  1803. }
  1804. }
  1805. if (!wroteKeys) {
  1806. let recordId = transition[RECORD_SYMBOL];
  1807. if (recordId)
  1808. target[objectOffset + start] = recordId;
  1809. else
  1810. insertNewRecord(transition, Object.keys(object), objectOffset, 0);
  1811. }
  1812. } :
  1813. (object) => {
  1814. let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
  1815. let newTransitions = 0;
  1816. for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
  1817. nextTransition = transition[key];
  1818. if (!nextTransition) {
  1819. nextTransition = transition[key] = Object.create(null);
  1820. newTransitions++;
  1821. }
  1822. transition = nextTransition;
  1823. }
  1824. let recordId = transition[RECORD_SYMBOL];
  1825. if (recordId) {
  1826. if (recordId >= 0x60 && useTwoByteRecords) {
  1827. target[position++] = ((recordId -= 0x60) & 0x1f) + 0x60;
  1828. target[position++] = recordId >> 5;
  1829. } else
  1830. target[position++] = recordId;
  1831. } else {
  1832. newRecord(transition, transition.__keys__ || Object.keys(object), newTransitions);
  1833. }
  1834. // now write the values
  1835. for (let key in object)
  1836. if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
  1837. pack(object[key]);
  1838. }
  1839. };
  1840. // create reference to useRecords if useRecords is a function
  1841. const checkUseRecords = typeof this.useRecords == 'function' && this.useRecords;
  1842. const writeObject = checkUseRecords ? (object) => {
  1843. checkUseRecords(object) ? writeRecord(object) : writePlainObject(object);
  1844. } : writeRecord;
  1845. const makeRoom = (end) => {
  1846. let newSize;
  1847. if (end > 0x1000000) {
  1848. // special handling for really large buffers
  1849. if ((end - start) > MAX_BUFFER_SIZE)
  1850. throw new Error('Packed buffer would be larger than maximum buffer size')
  1851. newSize = Math.min(MAX_BUFFER_SIZE,
  1852. Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000);
  1853. } else // faster handling for smaller buffers
  1854. newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12;
  1855. let newBuffer = new ByteArrayAllocate(newSize);
  1856. targetView = newBuffer.dataView || (newBuffer.dataView = new DataView(newBuffer.buffer, 0, newSize));
  1857. end = Math.min(end, target.length);
  1858. if (target.copy)
  1859. target.copy(newBuffer, 0, start, end);
  1860. else
  1861. newBuffer.set(target.slice(start, end));
  1862. position -= start;
  1863. start = 0;
  1864. safeEnd = newBuffer.length - 10;
  1865. return target = newBuffer
  1866. };
  1867. const newRecord = (transition, keys, newTransitions) => {
  1868. let recordId = structures.nextId;
  1869. if (!recordId)
  1870. recordId = 0x40;
  1871. if (recordId < sharedLimitId && this.shouldShareStructure && !this.shouldShareStructure(keys)) {
  1872. recordId = structures.nextOwnId;
  1873. if (!(recordId < maxStructureId))
  1874. recordId = sharedLimitId;
  1875. structures.nextOwnId = recordId + 1;
  1876. } else {
  1877. if (recordId >= maxStructureId)// cycle back around
  1878. recordId = sharedLimitId;
  1879. structures.nextId = recordId + 1;
  1880. }
  1881. let highByte = keys.highByte = recordId >= 0x60 && useTwoByteRecords ? (recordId - 0x60) >> 5 : -1;
  1882. transition[RECORD_SYMBOL] = recordId;
  1883. transition.__keys__ = keys;
  1884. structures[recordId - 0x40] = keys;
  1885. if (recordId < sharedLimitId) {
  1886. keys.isShared = true;
  1887. structures.sharedLength = recordId - 0x3f;
  1888. hasSharedUpdate = true;
  1889. if (highByte >= 0) {
  1890. target[position++] = (recordId & 0x1f) + 0x60;
  1891. target[position++] = highByte;
  1892. } else {
  1893. target[position++] = recordId;
  1894. }
  1895. } else {
  1896. if (highByte >= 0) {
  1897. target[position++] = 0xd5; // fixext 2
  1898. target[position++] = 0x72; // "r" record defintion extension type
  1899. target[position++] = (recordId & 0x1f) + 0x60;
  1900. target[position++] = highByte;
  1901. } else {
  1902. target[position++] = 0xd4; // fixext 1
  1903. target[position++] = 0x72; // "r" record defintion extension type
  1904. target[position++] = recordId;
  1905. }
  1906. if (newTransitions)
  1907. transitionsCount += serializationsSinceTransitionRebuild * newTransitions;
  1908. // record the removal of the id, we can maintain our shared structure
  1909. if (recordIdsToRemove.length >= maxOwnStructures)
  1910. recordIdsToRemove.shift()[RECORD_SYMBOL] = 0; // we are cycling back through, and have to remove old ones
  1911. recordIdsToRemove.push(transition);
  1912. pack(keys);
  1913. }
  1914. };
  1915. const insertNewRecord = (transition, keys, insertionOffset, newTransitions) => {
  1916. let mainTarget = target;
  1917. let mainPosition = position;
  1918. let mainSafeEnd = safeEnd;
  1919. let mainStart = start;
  1920. target = keysTarget;
  1921. position = 0;
  1922. start = 0;
  1923. if (!target)
  1924. keysTarget = target = new ByteArrayAllocate(8192);
  1925. safeEnd = target.length - 10;
  1926. newRecord(transition, keys, newTransitions);
  1927. keysTarget = target;
  1928. let keysPosition = position;
  1929. target = mainTarget;
  1930. position = mainPosition;
  1931. safeEnd = mainSafeEnd;
  1932. start = mainStart;
  1933. if (keysPosition > 1) {
  1934. let newEnd = position + keysPosition - 1;
  1935. if (newEnd > safeEnd)
  1936. makeRoom(newEnd);
  1937. let insertionPosition = insertionOffset + start;
  1938. target.copyWithin(insertionPosition + keysPosition, insertionPosition + 1, position);
  1939. target.set(keysTarget.slice(0, keysPosition), insertionPosition);
  1940. position = newEnd;
  1941. } else {
  1942. target[insertionOffset + start] = keysTarget[0];
  1943. }
  1944. };
  1945. const writeStruct = (object) => {
  1946. let newPosition = writeStructSlots(object, target, start, position, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
  1947. if (notifySharedUpdate)
  1948. return hasSharedUpdate = true;
  1949. position = newPosition;
  1950. let startTarget = target;
  1951. pack(value);
  1952. resetStructures();
  1953. if (startTarget !== target) {
  1954. return { position, targetView, target }; // indicate the buffer was re-allocated
  1955. }
  1956. return position;
  1957. }, this);
  1958. if (newPosition === 0) // bail and go to a msgpack object
  1959. return writeObject(object);
  1960. position = newPosition;
  1961. };
  1962. }
  1963. useBuffer(buffer) {
  1964. // this means we are finished using our own buffer and we can write over it safely
  1965. target = buffer;
  1966. target.dataView || (target.dataView = new DataView(target.buffer, target.byteOffset, target.byteLength));
  1967. position = 0;
  1968. }
  1969. set position (value) {
  1970. position = value;
  1971. }
  1972. get position() {
  1973. return position;
  1974. }
  1975. clearSharedData() {
  1976. if (this.structures)
  1977. this.structures = [];
  1978. if (this.typedStructs)
  1979. this.typedStructs = [];
  1980. }
  1981. };
  1982. extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, C1Type ];
  1983. extensions = [{
  1984. pack(date, allocateForWrite, pack) {
  1985. let seconds = date.getTime() / 1000;
  1986. if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
  1987. // Timestamp 32
  1988. let { target, targetView, position} = allocateForWrite(6);
  1989. target[position++] = 0xd6;
  1990. target[position++] = 0xff;
  1991. targetView.setUint32(position, seconds);
  1992. } else if (seconds > 0 && seconds < 0x100000000) {
  1993. // Timestamp 64
  1994. let { target, targetView, position} = allocateForWrite(10);
  1995. target[position++] = 0xd7;
  1996. target[position++] = 0xff;
  1997. targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0));
  1998. targetView.setUint32(position + 4, seconds);
  1999. } else if (isNaN(seconds)) {
  2000. if (this.onInvalidDate) {
  2001. allocateForWrite(0);
  2002. return pack(this.onInvalidDate())
  2003. }
  2004. // Intentionally invalid timestamp
  2005. let { target, targetView, position} = allocateForWrite(3);
  2006. target[position++] = 0xd4;
  2007. target[position++] = 0xff;
  2008. target[position++] = 0xff;
  2009. } else {
  2010. // Timestamp 96
  2011. let { target, targetView, position} = allocateForWrite(15);
  2012. target[position++] = 0xc7;
  2013. target[position++] = 12;
  2014. target[position++] = 0xff;
  2015. targetView.setUint32(position, date.getMilliseconds() * 1000000);
  2016. targetView.setBigInt64(position + 4, BigInt(Math.floor(seconds)));
  2017. }
  2018. }
  2019. }, {
  2020. pack(set, allocateForWrite, pack) {
  2021. if (this.setAsEmptyObject) {
  2022. allocateForWrite(0);
  2023. return pack({})
  2024. }
  2025. let array = Array.from(set);
  2026. let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0);
  2027. if (this.moreTypes) {
  2028. target[position++] = 0xd4;
  2029. target[position++] = 0x73; // 's' for Set
  2030. target[position++] = 0;
  2031. }
  2032. pack(array);
  2033. }
  2034. }, {
  2035. pack(error, allocateForWrite, pack) {
  2036. let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0);
  2037. if (this.moreTypes) {
  2038. target[position++] = 0xd4;
  2039. target[position++] = 0x65; // 'e' for error
  2040. target[position++] = 0;
  2041. }
  2042. pack([ error.name, error.message, error.cause ]);
  2043. }
  2044. }, {
  2045. pack(regex, allocateForWrite, pack) {
  2046. let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0);
  2047. if (this.moreTypes) {
  2048. target[position++] = 0xd4;
  2049. target[position++] = 0x78; // 'x' for regeXp
  2050. target[position++] = 0;
  2051. }
  2052. pack([ regex.source, regex.flags ]);
  2053. }
  2054. }, {
  2055. pack(arrayBuffer, allocateForWrite) {
  2056. if (this.moreTypes)
  2057. writeExtBuffer(arrayBuffer, 0x10, allocateForWrite);
  2058. else
  2059. writeBuffer(hasNodeBuffer$1 ? Buffer.from(arrayBuffer) : new Uint8Array(arrayBuffer), allocateForWrite);
  2060. }
  2061. }, {
  2062. pack(typedArray, allocateForWrite) {
  2063. let constructor = typedArray.constructor;
  2064. if (constructor !== ByteArray && this.moreTypes)
  2065. writeExtBuffer(typedArray, typedArrays.indexOf(constructor.name), allocateForWrite);
  2066. else
  2067. writeBuffer(typedArray, allocateForWrite);
  2068. }
  2069. }, {
  2070. pack(c1, allocateForWrite) { // specific 0xC1 object
  2071. let { target, position} = allocateForWrite(1);
  2072. target[position] = 0xc1;
  2073. }
  2074. }];
  2075. function writeExtBuffer(typedArray, type, allocateForWrite, encode) {
  2076. let length = typedArray.byteLength;
  2077. if (length + 1 < 0x100) {
  2078. var { target, position } = allocateForWrite(4 + length);
  2079. target[position++] = 0xc7;
  2080. target[position++] = length + 1;
  2081. } else if (length + 1 < 0x10000) {
  2082. var { target, position } = allocateForWrite(5 + length);
  2083. target[position++] = 0xc8;
  2084. target[position++] = (length + 1) >> 8;
  2085. target[position++] = (length + 1) & 0xff;
  2086. } else {
  2087. var { target, position, targetView } = allocateForWrite(7 + length);
  2088. target[position++] = 0xc9;
  2089. targetView.setUint32(position, length + 1); // plus one for the type byte
  2090. position += 4;
  2091. }
  2092. target[position++] = 0x74; // "t" for typed array
  2093. target[position++] = type;
  2094. if (!typedArray.buffer) typedArray = new Uint8Array(typedArray);
  2095. target.set(new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength), position);
  2096. }
  2097. function writeBuffer(buffer, allocateForWrite) {
  2098. let length = buffer.byteLength;
  2099. var target, position;
  2100. if (length < 0x100) {
  2101. var { target, position } = allocateForWrite(length + 2);
  2102. target[position++] = 0xc4;
  2103. target[position++] = length;
  2104. } else if (length < 0x10000) {
  2105. var { target, position } = allocateForWrite(length + 3);
  2106. target[position++] = 0xc5;
  2107. target[position++] = length >> 8;
  2108. target[position++] = length & 0xff;
  2109. } else {
  2110. var { target, position, targetView } = allocateForWrite(length + 5);
  2111. target[position++] = 0xc6;
  2112. targetView.setUint32(position, length);
  2113. position += 4;
  2114. }
  2115. target.set(buffer, position);
  2116. }
  2117. function writeExtensionData(result, target, position, type) {
  2118. let length = result.length;
  2119. switch (length) {
  2120. case 1:
  2121. target[position++] = 0xd4;
  2122. break
  2123. case 2:
  2124. target[position++] = 0xd5;
  2125. break
  2126. case 4:
  2127. target[position++] = 0xd6;
  2128. break
  2129. case 8:
  2130. target[position++] = 0xd7;
  2131. break
  2132. case 16:
  2133. target[position++] = 0xd8;
  2134. break
  2135. default:
  2136. if (length < 0x100) {
  2137. target[position++] = 0xc7;
  2138. target[position++] = length;
  2139. } else if (length < 0x10000) {
  2140. target[position++] = 0xc8;
  2141. target[position++] = length >> 8;
  2142. target[position++] = length & 0xff;
  2143. } else {
  2144. target[position++] = 0xc9;
  2145. target[position++] = length >> 24;
  2146. target[position++] = (length >> 16) & 0xff;
  2147. target[position++] = (length >> 8) & 0xff;
  2148. target[position++] = length & 0xff;
  2149. }
  2150. }
  2151. target[position++] = type;
  2152. target.set(result, position);
  2153. position += length;
  2154. return position
  2155. }
  2156. function insertIds(serialized, idsToInsert) {
  2157. // insert the ids that need to be referenced for structured clones
  2158. let nextId;
  2159. let distanceToMove = idsToInsert.length * 6;
  2160. let lastEnd = serialized.length - distanceToMove;
  2161. while (nextId = idsToInsert.pop()) {
  2162. let offset = nextId.offset;
  2163. let id = nextId.id;
  2164. serialized.copyWithin(offset + distanceToMove, offset, lastEnd);
  2165. distanceToMove -= 6;
  2166. let position = offset + distanceToMove;
  2167. serialized[position++] = 0xd6;
  2168. serialized[position++] = 0x69; // 'i'
  2169. serialized[position++] = id >> 24;
  2170. serialized[position++] = (id >> 16) & 0xff;
  2171. serialized[position++] = (id >> 8) & 0xff;
  2172. serialized[position++] = id & 0xff;
  2173. lastEnd = offset;
  2174. }
  2175. return serialized
  2176. }
  2177. function writeBundles(start, pack, incrementPosition) {
  2178. if (bundledStrings.length > 0) {
  2179. targetView.setUint32(bundledStrings.position + start, position + incrementPosition - bundledStrings.position - start);
  2180. bundledStrings.stringsPosition = position - start;
  2181. let writeStrings = bundledStrings;
  2182. bundledStrings = null;
  2183. pack(writeStrings[0]);
  2184. pack(writeStrings[1]);
  2185. }
  2186. }
  2187. function addExtension$1(extension) {
  2188. if (extension.Class) {
  2189. if (!extension.pack && !extension.write)
  2190. throw new Error('Extension has no pack or write function')
  2191. if (extension.pack && !extension.type)
  2192. throw new Error('Extension has no type (numeric code to identify the extension)')
  2193. extensionClasses.unshift(extension.Class);
  2194. extensions.unshift(extension);
  2195. }
  2196. addExtension$2(extension);
  2197. }
  2198. function prepareStructures$1(structures, packr) {
  2199. structures.isCompatible = (existingStructures) => {
  2200. let compatible = !existingStructures || ((packr.lastNamedStructuresLength || 0) === existingStructures.length);
  2201. if (!compatible) // we want to merge these existing structures immediately since we already have it and we are in the right transaction
  2202. packr._mergeStructures(existingStructures);
  2203. return compatible;
  2204. };
  2205. return structures
  2206. }
  2207. function setWriteStructSlots(writeSlots, makeStructures) {
  2208. writeStructSlots = writeSlots;
  2209. prepareStructures$1 = makeStructures;
  2210. }
  2211. let defaultPackr = new Packr$1({ useRecords: false });
  2212. const pack$1 = defaultPackr.pack;
  2213. defaultPackr.pack;
  2214. const REUSE_BUFFER_MODE = 512;
  2215. const RESET_BUFFER_MODE = 1024;
  2216. const RESERVE_START_SPACE = 2048;
  2217. const ASCII = 3; // the MIBenum from https://www.iana.org/assignments/character-sets/character-sets.xhtml (and other character encodings could be referenced by MIBenum)
  2218. const NUMBER = 0;
  2219. const UTF8 = 2;
  2220. const OBJECT_DATA = 1;
  2221. const DATE = 16;
  2222. const TYPE_NAMES = ['num', 'object', 'string', 'ascii'];
  2223. TYPE_NAMES[DATE] = 'date';
  2224. const float32Headers = [false, true, true, false, false, true, true, false];
  2225. let evalSupported;
  2226. try {
  2227. new Function('');
  2228. evalSupported = true;
  2229. } catch(error) {
  2230. // if eval variants are not supported, do not create inline object readers ever
  2231. }
  2232. let updatedPosition;
  2233. const hasNodeBuffer = typeof Buffer !== 'undefined';
  2234. let textEncoder, currentSource;
  2235. try {
  2236. textEncoder = new TextEncoder();
  2237. } catch (error) {}
  2238. const encodeUtf8 = hasNodeBuffer ? function(target, string, position) {
  2239. return target.utf8Write(string, position, target.byteLength - position)
  2240. } : (textEncoder && textEncoder.encodeInto) ?
  2241. function(target, string, position) {
  2242. return textEncoder.encodeInto(string, target.subarray(position)).written
  2243. } : false;
  2244. setWriteStructSlots(writeStruct, prepareStructures);
  2245. function writeStruct(object, target, encodingStart, position, structures, makeRoom, pack, packr) {
  2246. let typedStructs = packr.typedStructs || (packr.typedStructs = []);
  2247. // note that we rely on pack.js to load stored structures before we get to this point
  2248. let targetView = target.dataView;
  2249. let refsStartPosition = (typedStructs.lastStringStart || 100) + position;
  2250. let safeEnd = target.length - 10;
  2251. let start = position;
  2252. if (position > safeEnd) {
  2253. target = makeRoom(position);
  2254. targetView = target.dataView;
  2255. position -= encodingStart;
  2256. start -= encodingStart;
  2257. refsStartPosition -= encodingStart;
  2258. encodingStart = 0;
  2259. safeEnd = target.length - 10;
  2260. }
  2261. let refOffset, refPosition = refsStartPosition;
  2262. let transition = typedStructs.transitions || (typedStructs.transitions = Object.create(null));
  2263. let nextId = typedStructs.nextId || typedStructs.length;
  2264. let headerSize =
  2265. nextId < 0xf ? 1 :
  2266. nextId < 0xf0 ? 2 :
  2267. nextId < 0xf000 ? 3 :
  2268. nextId < 0xf00000 ? 4 : 0;
  2269. if (headerSize === 0)
  2270. return 0;
  2271. position += headerSize;
  2272. let queuedReferences = [];
  2273. let usedAscii0;
  2274. let keyIndex = 0;
  2275. for (let key in object) {
  2276. let value = object[key];
  2277. let nextTransition = transition[key];
  2278. if (!nextTransition) {
  2279. transition[key] = nextTransition = {
  2280. key,
  2281. parent: transition,
  2282. enumerationOffset: 0,
  2283. ascii0: null,
  2284. ascii8: null,
  2285. num8: null,
  2286. string16: null,
  2287. object16: null,
  2288. num32: null,
  2289. float64: null,
  2290. date64: null
  2291. };
  2292. }
  2293. if (position > safeEnd) {
  2294. target = makeRoom(position);
  2295. targetView = target.dataView;
  2296. position -= encodingStart;
  2297. start -= encodingStart;
  2298. refsStartPosition -= encodingStart;
  2299. refPosition -= encodingStart;
  2300. encodingStart = 0;
  2301. safeEnd = target.length - 10;
  2302. }
  2303. switch (typeof value) {
  2304. case 'number':
  2305. let number = value;
  2306. // first check to see if we are using a lot of ids and should default to wide/common format
  2307. if (nextId < 200 || !nextTransition.num64) {
  2308. if (number >> 0 === number && number < 0x20000000 && number > -0x1f000000) {
  2309. if (number < 0xf6 && number >= 0 && (nextTransition.num8 && !(nextId > 200 && nextTransition.num32) || number < 0x20 && !nextTransition.num32)) {
  2310. transition = nextTransition.num8 || createTypeTransition(nextTransition, NUMBER, 1);
  2311. target[position++] = number;
  2312. } else {
  2313. transition = nextTransition.num32 || createTypeTransition(nextTransition, NUMBER, 4);
  2314. targetView.setUint32(position, number, true);
  2315. position += 4;
  2316. }
  2317. break;
  2318. } else if (number < 0x100000000 && number >= -0x80000000) {
  2319. targetView.setFloat32(position, number, true);
  2320. if (float32Headers[target[position + 3] >>> 5]) {
  2321. let xShifted;
  2322. // this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
  2323. if (((xShifted = number * mult10[((target[position + 3] & 0x7f) << 1) | (target[position + 2] >> 7)]) >> 0) === xShifted) {
  2324. transition = nextTransition.num32 || createTypeTransition(nextTransition, NUMBER, 4);
  2325. position += 4;
  2326. break;
  2327. }
  2328. }
  2329. }
  2330. }
  2331. transition = nextTransition.num64 || createTypeTransition(nextTransition, NUMBER, 8);
  2332. targetView.setFloat64(position, number, true);
  2333. position += 8;
  2334. break;
  2335. case 'string':
  2336. let strLength = value.length;
  2337. refOffset = refPosition - refsStartPosition;
  2338. if ((strLength << 2) + refPosition > safeEnd) {
  2339. target = makeRoom((strLength << 2) + refPosition);
  2340. targetView = target.dataView;
  2341. position -= encodingStart;
  2342. start -= encodingStart;
  2343. refsStartPosition -= encodingStart;
  2344. refPosition -= encodingStart;
  2345. encodingStart = 0;
  2346. safeEnd = target.length - 10;
  2347. }
  2348. if (strLength > ((0xff00 + refOffset) >> 2)) {
  2349. queuedReferences.push(key, value, position - start);
  2350. break;
  2351. }
  2352. let isNotAscii;
  2353. let strStart = refPosition;
  2354. if (strLength < 0x40) {
  2355. let i, c1, c2;
  2356. for (i = 0; i < strLength; i++) {
  2357. c1 = value.charCodeAt(i);
  2358. if (c1 < 0x80) {
  2359. target[refPosition++] = c1;
  2360. } else if (c1 < 0x800) {
  2361. isNotAscii = true;
  2362. target[refPosition++] = c1 >> 6 | 0xc0;
  2363. target[refPosition++] = c1 & 0x3f | 0x80;
  2364. } else if (
  2365. (c1 & 0xfc00) === 0xd800 &&
  2366. ((c2 = value.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
  2367. ) {
  2368. isNotAscii = true;
  2369. c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff);
  2370. i++;
  2371. target[refPosition++] = c1 >> 18 | 0xf0;
  2372. target[refPosition++] = c1 >> 12 & 0x3f | 0x80;
  2373. target[refPosition++] = c1 >> 6 & 0x3f | 0x80;
  2374. target[refPosition++] = c1 & 0x3f | 0x80;
  2375. } else {
  2376. isNotAscii = true;
  2377. target[refPosition++] = c1 >> 12 | 0xe0;
  2378. target[refPosition++] = c1 >> 6 & 0x3f | 0x80;
  2379. target[refPosition++] = c1 & 0x3f | 0x80;
  2380. }
  2381. }
  2382. } else {
  2383. refPosition += encodeUtf8(target, value, refPosition);
  2384. isNotAscii = refPosition - strStart > strLength;
  2385. }
  2386. if (refOffset < 0xa0 || (refOffset < 0xf6 && (nextTransition.ascii8 || nextTransition.string8))) {
  2387. // short strings
  2388. if (isNotAscii) {
  2389. if (!(transition = nextTransition.string8)) {
  2390. if (typedStructs.length > 10 && (transition = nextTransition.ascii8)) {
  2391. // we can safely change ascii to utf8 in place since they are compatible
  2392. transition.__type = UTF8;
  2393. nextTransition.ascii8 = null;
  2394. nextTransition.string8 = transition;
  2395. pack(null, 0, true); // special call to notify that structures have been updated
  2396. } else {
  2397. transition = createTypeTransition(nextTransition, UTF8, 1);
  2398. }
  2399. }
  2400. } else if (refOffset === 0 && !usedAscii0) {
  2401. usedAscii0 = true;
  2402. transition = nextTransition.ascii0 || createTypeTransition(nextTransition, ASCII, 0);
  2403. break; // don't increment position
  2404. }// else ascii:
  2405. else if (!(transition = nextTransition.ascii8) && !(typedStructs.length > 10 && (transition = nextTransition.string8)))
  2406. transition = createTypeTransition(nextTransition, ASCII, 1);
  2407. target[position++] = refOffset;
  2408. } else {
  2409. // TODO: Enable ascii16 at some point, but get the logic right
  2410. //if (isNotAscii)
  2411. transition = nextTransition.string16 || createTypeTransition(nextTransition, UTF8, 2);
  2412. //else
  2413. //transition = nextTransition.ascii16 || createTypeTransition(nextTransition, ASCII, 2);
  2414. targetView.setUint16(position, refOffset, true);
  2415. position += 2;
  2416. }
  2417. break;
  2418. case 'object':
  2419. if (value) {
  2420. if (value.constructor === Date) {
  2421. transition = nextTransition.date64 || createTypeTransition(nextTransition, DATE, 8);
  2422. targetView.setFloat64(position, value.getTime(), true);
  2423. position += 8;
  2424. } else {
  2425. queuedReferences.push(key, value, keyIndex);
  2426. }
  2427. break;
  2428. } else { // null
  2429. nextTransition = anyType(nextTransition, position, targetView, -10); // match CBOR with this
  2430. if (nextTransition) {
  2431. transition = nextTransition;
  2432. position = updatedPosition;
  2433. } else queuedReferences.push(key, value, keyIndex);
  2434. }
  2435. break;
  2436. case 'boolean':
  2437. transition = nextTransition.num8 || nextTransition.ascii8 || createTypeTransition(nextTransition, NUMBER, 1);
  2438. target[position++] = value ? 0xf9 : 0xf8; // match CBOR with these
  2439. break;
  2440. case 'undefined':
  2441. nextTransition = anyType(nextTransition, position, targetView, -9); // match CBOR with this
  2442. if (nextTransition) {
  2443. transition = nextTransition;
  2444. position = updatedPosition;
  2445. } else queuedReferences.push(key, value, keyIndex);
  2446. break;
  2447. default:
  2448. queuedReferences.push(key, value, keyIndex);
  2449. }
  2450. keyIndex++;
  2451. }
  2452. for (let i = 0, l = queuedReferences.length; i < l;) {
  2453. let key = queuedReferences[i++];
  2454. let value = queuedReferences[i++];
  2455. let propertyIndex = queuedReferences[i++];
  2456. let nextTransition = transition[key];
  2457. if (!nextTransition) {
  2458. transition[key] = nextTransition = {
  2459. key,
  2460. parent: transition,
  2461. enumerationOffset: propertyIndex - keyIndex,
  2462. ascii0: null,
  2463. ascii8: null,
  2464. num8: null,
  2465. string16: null,
  2466. object16: null,
  2467. num32: null,
  2468. float64: null
  2469. };
  2470. }
  2471. let newPosition;
  2472. if (value) {
  2473. /*if (typeof value === 'string') { // TODO: we could re-enable long strings
  2474. if (position + value.length * 3 > safeEnd) {
  2475. target = makeRoom(position + value.length * 3);
  2476. position -= start;
  2477. targetView = target.dataView;
  2478. start = 0;
  2479. }
  2480. newPosition = position + target.utf8Write(value, position, 0xffffffff);
  2481. } else { */
  2482. let size;
  2483. refOffset = refPosition - refsStartPosition;
  2484. if (refOffset < 0xff00) {
  2485. transition = nextTransition.object16;
  2486. if (transition)
  2487. size = 2;
  2488. else if ((transition = nextTransition.object32))
  2489. size = 4;
  2490. else {
  2491. transition = createTypeTransition(nextTransition, OBJECT_DATA, 2);
  2492. size = 2;
  2493. }
  2494. } else {
  2495. transition = nextTransition.object32 || createTypeTransition(nextTransition, OBJECT_DATA, 4);
  2496. size = 4;
  2497. }
  2498. newPosition = pack(value, refPosition);
  2499. //}
  2500. if (typeof newPosition === 'object') {
  2501. // re-allocated
  2502. refPosition = newPosition.position;
  2503. targetView = newPosition.targetView;
  2504. target = newPosition.target;
  2505. refsStartPosition -= encodingStart;
  2506. position -= encodingStart;
  2507. start -= encodingStart;
  2508. encodingStart = 0;
  2509. } else
  2510. refPosition = newPosition;
  2511. if (size === 2) {
  2512. targetView.setUint16(position, refOffset, true);
  2513. position += 2;
  2514. } else {
  2515. targetView.setUint32(position, refOffset, true);
  2516. position += 4;
  2517. }
  2518. } else { // null or undefined
  2519. transition = nextTransition.object16 || createTypeTransition(nextTransition, OBJECT_DATA, 2);
  2520. targetView.setInt16(position, value === null ? -10 : -9, true);
  2521. position += 2;
  2522. }
  2523. keyIndex++;
  2524. }
  2525. let recordId = transition[RECORD_SYMBOL];
  2526. if (recordId == null) {
  2527. recordId = packr.typedStructs.length;
  2528. let structure = [];
  2529. let nextTransition = transition;
  2530. let key, type;
  2531. while ((type = nextTransition.__type) !== undefined) {
  2532. let size = nextTransition.__size;
  2533. nextTransition = nextTransition.__parent;
  2534. key = nextTransition.key;
  2535. let property = [type, size, key];
  2536. if (nextTransition.enumerationOffset)
  2537. property.push(nextTransition.enumerationOffset);
  2538. structure.push(property);
  2539. nextTransition = nextTransition.parent;
  2540. }
  2541. structure.reverse();
  2542. transition[RECORD_SYMBOL] = recordId;
  2543. packr.typedStructs[recordId] = structure;
  2544. pack(null, 0, true); // special call to notify that structures have been updated
  2545. }
  2546. switch (headerSize) {
  2547. case 1:
  2548. if (recordId >= 0x10) return 0;
  2549. target[start] = recordId + 0x20;
  2550. break;
  2551. case 2:
  2552. if (recordId >= 0x100) return 0;
  2553. target[start] = 0x38;
  2554. target[start + 1] = recordId;
  2555. break;
  2556. case 3:
  2557. if (recordId >= 0x10000) return 0;
  2558. target[start] = 0x39;
  2559. targetView.setUint16(start + 1, recordId, true);
  2560. break;
  2561. case 4:
  2562. if (recordId >= 0x1000000) return 0;
  2563. targetView.setUint32(start, (recordId << 8) + 0x3a, true);
  2564. break;
  2565. }
  2566. if (position < refsStartPosition) {
  2567. if (refsStartPosition === refPosition)
  2568. return position; // no refs
  2569. // adjust positioning
  2570. target.copyWithin(position, refsStartPosition, refPosition);
  2571. refPosition += position - refsStartPosition;
  2572. typedStructs.lastStringStart = position - start;
  2573. } else if (position > refsStartPosition) {
  2574. if (refsStartPosition === refPosition)
  2575. return position; // no refs
  2576. typedStructs.lastStringStart = position - start;
  2577. return writeStruct(object, target, encodingStart, start, structures, makeRoom, pack, packr);
  2578. }
  2579. return refPosition;
  2580. }
  2581. function anyType(transition, position, targetView, value) {
  2582. let nextTransition;
  2583. if ((nextTransition = transition.ascii8 || transition.num8)) {
  2584. targetView.setInt8(position, value, true);
  2585. updatedPosition = position + 1;
  2586. return nextTransition;
  2587. }
  2588. if ((nextTransition = transition.string16 || transition.object16)) {
  2589. targetView.setInt16(position, value, true);
  2590. updatedPosition = position + 2;
  2591. return nextTransition;
  2592. }
  2593. if (nextTransition = transition.num32) {
  2594. targetView.setUint32(position, 0xe0000100 + value, true);
  2595. updatedPosition = position + 4;
  2596. return nextTransition;
  2597. }
  2598. // transition.float64
  2599. if (nextTransition = transition.num64) {
  2600. targetView.setFloat64(position, NaN, true);
  2601. targetView.setInt8(position, value);
  2602. updatedPosition = position + 8;
  2603. return nextTransition;
  2604. }
  2605. updatedPosition = position;
  2606. // TODO: can we do an "any" type where we defer the decision?
  2607. return;
  2608. }
  2609. function createTypeTransition(transition, type, size) {
  2610. let typeName = TYPE_NAMES[type] + (size << 3);
  2611. let newTransition = transition[typeName] || (transition[typeName] = Object.create(null));
  2612. newTransition.__type = type;
  2613. newTransition.__size = size;
  2614. newTransition.__parent = transition;
  2615. return newTransition;
  2616. }
  2617. function onLoadedStructures(sharedData) {
  2618. if (!(sharedData instanceof Map))
  2619. return sharedData;
  2620. let typed = sharedData.get('typed') || [];
  2621. if (Object.isFrozen(typed))
  2622. typed = typed.map(structure => structure.slice(0));
  2623. let named = sharedData.get('named');
  2624. let transitions = Object.create(null);
  2625. for (let i = 0, l = typed.length; i < l; i++) {
  2626. let structure = typed[i];
  2627. let transition = transitions;
  2628. for (let [type, size, key] of structure) {
  2629. let nextTransition = transition[key];
  2630. if (!nextTransition) {
  2631. transition[key] = nextTransition = {
  2632. key,
  2633. parent: transition,
  2634. enumerationOffset: 0,
  2635. ascii0: null,
  2636. ascii8: null,
  2637. num8: null,
  2638. string16: null,
  2639. object16: null,
  2640. num32: null,
  2641. float64: null,
  2642. date64: null,
  2643. };
  2644. }
  2645. transition = createTypeTransition(nextTransition, type, size);
  2646. }
  2647. transition[RECORD_SYMBOL] = i;
  2648. }
  2649. typed.transitions = transitions;
  2650. this.typedStructs = typed;
  2651. this.lastTypedStructuresLength = typed.length;
  2652. return named;
  2653. }
  2654. var sourceSymbol = Symbol.for('source');
  2655. function readStruct(src, position, srcEnd, unpackr) {
  2656. let recordId = src[position++] - 0x20;
  2657. if (recordId >= 24) {
  2658. switch(recordId) {
  2659. case 24: recordId = src[position++]; break;
  2660. // little endian:
  2661. case 25: recordId = src[position++] + (src[position++] << 8); break;
  2662. case 26: recordId = src[position++] + (src[position++] << 8) + (src[position++] << 16); break;
  2663. case 27: recordId = src[position++] + (src[position++] << 8) + (src[position++] << 16) + (src[position++] << 24); break;
  2664. }
  2665. }
  2666. let structure = unpackr.typedStructs && unpackr.typedStructs[recordId];
  2667. if (!structure) {
  2668. // copy src buffer because getStructures will override it
  2669. src = Uint8Array.prototype.slice.call(src, position, srcEnd);
  2670. srcEnd -= position;
  2671. position = 0;
  2672. if (!unpackr.getStructures)
  2673. throw new Error(`Reference to shared structure ${recordId} without getStructures method`);
  2674. unpackr._mergeStructures(unpackr.getStructures());
  2675. if (!unpackr.typedStructs)
  2676. throw new Error('Could not find any shared typed structures');
  2677. unpackr.lastTypedStructuresLength = unpackr.typedStructs.length;
  2678. structure = unpackr.typedStructs[recordId];
  2679. if (!structure)
  2680. throw new Error('Could not find typed structure ' + recordId);
  2681. }
  2682. var construct = structure.construct;
  2683. if (!construct) {
  2684. construct = structure.construct = function LazyObject() {
  2685. };
  2686. var prototype = construct.prototype;
  2687. let properties = [];
  2688. let currentOffset = 0;
  2689. let lastRefProperty;
  2690. for (let i = 0, l = structure.length; i < l; i++) {
  2691. let definition = structure[i];
  2692. let [ type, size, key, enumerationOffset ] = definition;
  2693. if (key === '__proto__')
  2694. key = '__proto_';
  2695. let property = {
  2696. key,
  2697. offset: currentOffset,
  2698. };
  2699. if (enumerationOffset)
  2700. properties.splice(i + enumerationOffset, 0, property);
  2701. else
  2702. properties.push(property);
  2703. let getRef;
  2704. switch(size) { // TODO: Move into a separate function
  2705. case 0: getRef = () => 0; break;
  2706. case 1:
  2707. getRef = (source, position) => {
  2708. let ref = source.bytes[position + property.offset];
  2709. return ref >= 0xf6 ? toConstant(ref) : ref;
  2710. };
  2711. break;
  2712. case 2:
  2713. getRef = (source, position) => {
  2714. let src = source.bytes;
  2715. let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
  2716. let ref = dataView.getUint16(position + property.offset, true);
  2717. return ref >= 0xff00 ? toConstant(ref & 0xff) : ref;
  2718. };
  2719. break;
  2720. case 4:
  2721. getRef = (source, position) => {
  2722. let src = source.bytes;
  2723. let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
  2724. let ref = dataView.getUint32(position + property.offset, true);
  2725. return ref >= 0xffffff00 ? toConstant(ref & 0xff) : ref;
  2726. };
  2727. break;
  2728. }
  2729. property.getRef = getRef;
  2730. currentOffset += size;
  2731. let get;
  2732. switch(type) {
  2733. case ASCII:
  2734. if (lastRefProperty && !lastRefProperty.next)
  2735. lastRefProperty.next = property;
  2736. lastRefProperty = property;
  2737. property.multiGetCount = 0;
  2738. get = function(source) {
  2739. let src = source.bytes;
  2740. let position = source.position;
  2741. let refStart = currentOffset + position;
  2742. let ref = getRef(source, position);
  2743. if (typeof ref !== 'number') return ref;
  2744. let end, next = property.next;
  2745. while(next) {
  2746. end = next.getRef(source, position);
  2747. if (typeof end === 'number')
  2748. break;
  2749. else
  2750. end = null;
  2751. next = next.next;
  2752. }
  2753. if (end == null)
  2754. end = source.bytesEnd - refStart;
  2755. if (source.srcString) {
  2756. return source.srcString.slice(ref, end);
  2757. }
  2758. /*if (property.multiGetCount > 0) {
  2759. let asciiEnd;
  2760. next = firstRefProperty;
  2761. let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
  2762. do {
  2763. asciiEnd = dataView.getUint16(source.position + next.offset, true);
  2764. if (asciiEnd < 0xff00)
  2765. break;
  2766. else
  2767. asciiEnd = null;
  2768. } while((next = next.next));
  2769. if (asciiEnd == null)
  2770. asciiEnd = source.bytesEnd - refStart
  2771. source.srcString = src.toString('latin1', refStart, refStart + asciiEnd);
  2772. return source.srcString.slice(ref, end);
  2773. }
  2774. if (source.prevStringGet) {
  2775. source.prevStringGet.multiGetCount += 2;
  2776. } else {
  2777. source.prevStringGet = property;
  2778. property.multiGetCount--;
  2779. }*/
  2780. return readString(src, ref + refStart, end - ref);
  2781. //return src.toString('latin1', ref + refStart, end + refStart);
  2782. };
  2783. break;
  2784. case UTF8: case OBJECT_DATA:
  2785. if (lastRefProperty && !lastRefProperty.next)
  2786. lastRefProperty.next = property;
  2787. lastRefProperty = property;
  2788. get = function(source) {
  2789. let position = source.position;
  2790. let refStart = currentOffset + position;
  2791. let ref = getRef(source, position);
  2792. if (typeof ref !== 'number') return ref;
  2793. let src = source.bytes;
  2794. let end, next = property.next;
  2795. while(next) {
  2796. end = next.getRef(source, position);
  2797. if (typeof end === 'number')
  2798. break;
  2799. else
  2800. end = null;
  2801. next = next.next;
  2802. }
  2803. if (end == null)
  2804. end = source.bytesEnd - refStart;
  2805. if (type === UTF8) {
  2806. return src.toString('utf8', ref + refStart, end + refStart);
  2807. } else {
  2808. currentSource = source;
  2809. try {
  2810. return unpackr.unpack(src, { start: ref + refStart, end: end + refStart });
  2811. } finally {
  2812. currentSource = null;
  2813. }
  2814. }
  2815. };
  2816. break;
  2817. case NUMBER:
  2818. switch(size) {
  2819. case 4:
  2820. get = function (source) {
  2821. let src = source.bytes;
  2822. let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
  2823. let position = source.position + property.offset;
  2824. let value = dataView.getInt32(position, true);
  2825. if (value < 0x20000000) {
  2826. if (value > -0x1f000000)
  2827. return value;
  2828. if (value > -0x20000000)
  2829. return toConstant(value & 0xff);
  2830. }
  2831. let fValue = dataView.getFloat32(position, true);
  2832. // this does rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
  2833. let multiplier = mult10[((src[position + 3] & 0x7f) << 1) | (src[position + 2] >> 7)];
  2834. return ((multiplier * fValue + (fValue > 0 ? 0.5 : -0.5)) >> 0) / multiplier;
  2835. };
  2836. break;
  2837. case 8:
  2838. get = function (source) {
  2839. let src = source.bytes;
  2840. let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
  2841. let value = dataView.getFloat64(source.position + property.offset, true);
  2842. if (isNaN(value)) {
  2843. let byte = src[source.position + property.offset];
  2844. if (byte >= 0xf6)
  2845. return toConstant(byte);
  2846. }
  2847. return value;
  2848. };
  2849. break;
  2850. case 1:
  2851. get = function (source) {
  2852. let src = source.bytes;
  2853. let value = src[source.position + property.offset];
  2854. return value < 0xf6 ? value : toConstant(value);
  2855. };
  2856. break;
  2857. }
  2858. break;
  2859. case DATE:
  2860. get = function (source) {
  2861. let src = source.bytes;
  2862. let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
  2863. return new Date(dataView.getFloat64(source.position + property.offset, true));
  2864. };
  2865. break;
  2866. }
  2867. property.get = get;
  2868. }
  2869. // TODO: load the srcString for faster string decoding on toJSON
  2870. if (evalSupported) {
  2871. let objectLiteralProperties = [];
  2872. let args = [];
  2873. let i = 0;
  2874. let hasInheritedProperties;
  2875. for (let property of properties) { // assign in enumeration order
  2876. if (unpackr.alwaysLazyProperty && unpackr.alwaysLazyProperty(property.key)) {
  2877. // these properties are not eagerly evaluated and this can be used for creating properties
  2878. // that are not serialized as JSON
  2879. hasInheritedProperties = true;
  2880. continue;
  2881. }
  2882. Object.defineProperty(prototype, property.key, { get: withSource(property.get), enumerable: true });
  2883. let valueFunction = 'v' + i++;
  2884. args.push(valueFunction);
  2885. objectLiteralProperties.push('[' + JSON.stringify(property.key) + ']:' + valueFunction + '(s)');
  2886. }
  2887. if (hasInheritedProperties) {
  2888. objectLiteralProperties.push('__proto__:this');
  2889. }
  2890. let toObject = (new Function(...args, 'return function(s){return{' + objectLiteralProperties.join(',') + '}}')).apply(null, properties.map(prop => prop.get));
  2891. Object.defineProperty(prototype, 'toJSON', {
  2892. value(omitUnderscoredProperties) {
  2893. return toObject.call(this, this[sourceSymbol]);
  2894. }
  2895. });
  2896. } else {
  2897. Object.defineProperty(prototype, 'toJSON', {
  2898. value(omitUnderscoredProperties) {
  2899. // return an enumerable object with own properties to JSON stringify
  2900. let resolved = {};
  2901. for (let i = 0, l = properties.length; i < l; i++) {
  2902. // TODO: check alwaysLazyProperty
  2903. let key = properties[i].key;
  2904. resolved[key] = this[key];
  2905. }
  2906. return resolved;
  2907. },
  2908. // not enumerable or anything
  2909. });
  2910. }
  2911. }
  2912. var instance = new construct();
  2913. instance[sourceSymbol] = {
  2914. bytes: src,
  2915. position,
  2916. srcString: '',
  2917. bytesEnd: srcEnd
  2918. };
  2919. return instance;
  2920. }
  2921. function toConstant(code) {
  2922. switch(code) {
  2923. case 0xf6: return null;
  2924. case 0xf7: return undefined;
  2925. case 0xf8: return false;
  2926. case 0xf9: return true;
  2927. }
  2928. throw new Error('Unknown constant');
  2929. }
  2930. function withSource(get) {
  2931. return function() {
  2932. return get(this[sourceSymbol]);
  2933. }
  2934. }
  2935. function saveState() {
  2936. if (currentSource) {
  2937. currentSource.bytes = Uint8Array.prototype.slice.call(currentSource.bytes, currentSource.position, currentSource.bytesEnd);
  2938. currentSource.position = 0;
  2939. currentSource.bytesEnd = currentSource.bytes.length;
  2940. }
  2941. }
  2942. function prepareStructures(structures, packr) {
  2943. if (packr.typedStructs) {
  2944. let structMap = new Map();
  2945. structMap.set('named', structures);
  2946. structMap.set('typed', packr.typedStructs);
  2947. structures = structMap;
  2948. }
  2949. let lastTypedStructuresLength = packr.lastTypedStructuresLength || 0;
  2950. structures.isCompatible = existing => {
  2951. let compatible = true;
  2952. if (existing instanceof Map) {
  2953. let named = existing.get('named') || [];
  2954. if (named.length !== (packr.lastNamedStructuresLength || 0))
  2955. compatible = false;
  2956. let typed = existing.get('typed') || [];
  2957. if (typed.length !== lastTypedStructuresLength)
  2958. compatible = false;
  2959. } else if (existing instanceof Array || Array.isArray(existing)) {
  2960. if (existing.length !== (packr.lastNamedStructuresLength || 0))
  2961. compatible = false;
  2962. }
  2963. if (!compatible)
  2964. packr._mergeStructures(existing);
  2965. return compatible;
  2966. };
  2967. packr.lastTypedStructuresLength = packr.typedStructs && packr.typedStructs.length;
  2968. return structures;
  2969. }
  2970. setReadStruct(readStruct, onLoadedStructures, saveState);
  2971. const nativeAccelerationDisabled = process.env.MSGPACKR_NATIVE_ACCELERATION_DISABLED !== undefined && process.env.MSGPACKR_NATIVE_ACCELERATION_DISABLED.toLowerCase() === 'true';
  2972. if (!nativeAccelerationDisabled) {
  2973. let extractor;
  2974. try {
  2975. if (typeof require == 'function')
  2976. extractor = require('msgpackr-extract');
  2977. else
  2978. extractor = module.createRequire((document.currentScript && document.currentScript.src || new URL('test.js', document.baseURI).href))('msgpackr-extract');
  2979. if (extractor)
  2980. setExtractor(extractor.extractStrings);
  2981. } catch (error) {
  2982. // native module is optional
  2983. }
  2984. }
  2985. let allSampleData = [];
  2986. for (let i = 1; i < 6; i++) {
  2987. allSampleData.push(JSON.parse(fs.readFileSync(new URL(`./example${i > 1 ? i : ''}.json`, (document.currentScript && document.currentScript.src || new URL('test.js', document.baseURI).href)))));
  2988. }
  2989. allSampleData.push({
  2990. name: 'some other types',
  2991. date: new Date(),
  2992. empty: '',
  2993. });
  2994. const sampleData = allSampleData[3];
  2995. function tryRequire(module) {
  2996. try {
  2997. return require(module)
  2998. } catch(error) {
  2999. return {}
  3000. }
  3001. }
  3002. let seed = 0;
  3003. function random() {
  3004. seed++;
  3005. let a = seed * 15485863;
  3006. return (a * a * a % 2038074743) / 2038074743;
  3007. }
  3008. //if (typeof chai === 'undefined') { chai = require('chai') }
  3009. var assert = chai.assert;
  3010. //if (typeof msgpackr === 'undefined') { msgpackr = require('..') }
  3011. var Packr = Packr$1;
  3012. var Unpackr = Unpackr$1;
  3013. var unpack = unpack$1;
  3014. var unpackMultiple = unpackMultiple$1;
  3015. var roundFloat32 = roundFloat32$1;
  3016. var pack = pack$1;
  3017. var DECIMAL_FIT = FLOAT32_OPTIONS.DECIMAL_FIT;
  3018. var addExtension = addExtension$1;
  3019. var zlib = tryRequire('zlib');
  3020. zlib.deflateSync;
  3021. zlib.inflateSync;
  3022. zlib.brotliCompressSync;
  3023. zlib.brotliDecompressSync;
  3024. zlib.constants;
  3025. var ITERATIONS = 4000;
  3026. class ExtendArray extends Array {
  3027. }
  3028. class ExtendArray2 extends Array {
  3029. }
  3030. class ExtendArray3 extends Array {
  3031. }
  3032. class ExtendObject {
  3033. }
  3034. suite('msgpackr basic tests', function() {
  3035. test('pack/unpack data', function () {
  3036. var data = {
  3037. data: [
  3038. {a: 1, name: 'one', type: 'odd', isOdd: true},
  3039. {a: 2, name: 'two', type: 'even'},
  3040. {a: 3, name: 'three', type: 'odd', isOdd: true},
  3041. {a: 4, name: 'four', type: 'even'},
  3042. {a: 5, name: 'five', type: 'odd', isOdd: true},
  3043. {a: 6, name: 'six', type: 'even', isOdd: null}
  3044. ],
  3045. description: 'some names',
  3046. types: ['odd', 'even'],
  3047. convertEnumToNum: [
  3048. {prop: 'test'},
  3049. {prop: 'test'},
  3050. {prop: 'test'},
  3051. {prop: 1},
  3052. {prop: 2},
  3053. {prop: [undefined]},
  3054. {prop: null}
  3055. ]
  3056. };
  3057. let structures = [];
  3058. let packr = new Packr({structures});
  3059. var serialized = packr.pack(data);
  3060. serialized = packr.pack(data);
  3061. serialized = packr.pack(data);
  3062. var deserialized = packr.unpack(serialized);
  3063. assert.deepEqual(deserialized, data);
  3064. });
  3065. test('mixed structures', function () {
  3066. let data1 = {a: 1, b: 2, c: 3};
  3067. let data2 = {a: 1, b: 2, d: 4};
  3068. let data3 = {a: 1, b: 2, e: 5};
  3069. let structures = [];
  3070. let packr = new Packr({structures});
  3071. var serialized = packr.pack(data1);
  3072. var deserialized = packr.unpack(serialized);
  3073. assert.deepEqual(deserialized, data1);
  3074. var serialized = packr.pack(data2);
  3075. var deserialized = packr.unpack(serialized);
  3076. assert.deepEqual(deserialized, data2);
  3077. var serialized = packr.pack(data3);
  3078. var deserialized = packr.unpack(serialized);
  3079. assert.deepEqual(deserialized, data3);
  3080. });
  3081. test('mixed array', function () {
  3082. var data = [
  3083. 'one',
  3084. 'two',
  3085. 'one',
  3086. 10,
  3087. 11,
  3088. null,
  3089. true,
  3090. 'three',
  3091. 'three',
  3092. 'one', [
  3093. 3, -5, -50, -400, 1.3, -5.3, true
  3094. ]
  3095. ];
  3096. let structures = [];
  3097. let packr = new Packr({structures});
  3098. var serialized = packr.pack(data);
  3099. var deserialized = packr.unpack(serialized);
  3100. assert.deepEqual(deserialized, data);
  3101. });
  3102. test('255 chars', function () {
  3103. const data = 'RRZG9A6I7xupPeOZhxcOcioFsuhszGOdyDUcbRf4Zef2kdPIfC9RaLO4jTM5JhuZvTsF09fbRHMGtqk7YAgu3vespeTe9l61ziZ6VrMnYu2CamK96wCkmz0VUXyqaiUoTPgzk414LS9yYrd5uh7w18ksJF5SlC2e91rukWvNqAZJjYN3jpkqHNOFchCwFrhbxq2Lrv1kSJPYCx9blRg2hGmYqTbElLTZHv20iNqwZeQbRMgSBPT6vnbCBPnOh1W';
  3104. var serialized = pack(data);
  3105. var deserialized = unpack(serialized);
  3106. assert.equal(deserialized, data);
  3107. });
  3108. test('use ArrayBuffer', function () {
  3109. const data = {prop: 'a test'};
  3110. var serialized = pack(data);
  3111. let ab = new ArrayBuffer(serialized.length);
  3112. let u8 = new Uint8Array(ab);
  3113. u8.set(serialized);
  3114. var deserialized = unpack(ab);
  3115. assert.deepEqual(deserialized, data);
  3116. });
  3117. test('pack/unpack varying data with random access structures', function () {
  3118. let structures = [];
  3119. let packr = new Packr({
  3120. structures, useRecords: true, randomAccessStructure: true, freezeData: true, saveStructures(structures) {
  3121. }, getStructures() {
  3122. console.log('getStructures');
  3123. }
  3124. });
  3125. for (let i = 0; i < 2000; i++) {
  3126. let data = {};
  3127. let props = ['foo', 'bar', 'a', 'b', 'c', 'name', 'age', 'd'];
  3128. function makeString() {
  3129. let str = '';
  3130. while (random() < 0.9) {
  3131. str += random() < 0.8 ? 'hello world' : String.fromCharCode(300);
  3132. }
  3133. return str;
  3134. }
  3135. for (let i = 0; i < random() * 20; i++) {
  3136. data[props[Math.floor(random() * 8)]] =
  3137. random() < 0.3 ? Math.floor(random() * 400) / 2 :
  3138. random() < 0.3 ? makeString() : random() < 0.3 ? true : random() < 0.3 ? sampleData : null;
  3139. }
  3140. var serialized = packr.pack(data);
  3141. var deserialized = packr.unpack(serialized);
  3142. for (let key in deserialized) {
  3143. deserialized[key];
  3144. }
  3145. assert.deepEqual(deserialized, data);
  3146. }
  3147. });
  3148. for (let sampleData of allSampleData) {
  3149. let snippet = JSON.stringify(sampleData).slice(0, 20) + '...';
  3150. test('pack/unpack sample data ' + snippet, function () {
  3151. var data = sampleData;
  3152. var serialized = pack(data);
  3153. var deserialized = unpack(serialized);
  3154. assert.deepEqual(deserialized, data);
  3155. var serialized = pack(data);
  3156. var deserialized = unpack(serialized);
  3157. assert.deepEqual(deserialized, data);
  3158. });
  3159. test('pack/unpack sample data with Uint8Array encoding' + snippet, function () {
  3160. var data = sampleData;
  3161. var serialized = pack(data);
  3162. serialized = new Uint8Array(serialized);
  3163. var deserialized = unpack(serialized);
  3164. assert.deepEqual(deserialized, data);
  3165. var serialized = pack(data);
  3166. var deserialized = unpack(serialized);
  3167. assert.deepEqual(deserialized, data);
  3168. });
  3169. test('pack/unpack sample data with random access structures ' + snippet, function () {
  3170. var data = sampleData;
  3171. let structures = [];
  3172. let packr = new Packr({
  3173. structures, useRecords: true, randomAccessStructure: true, freezeData: true, saveStructures(structures) {
  3174. }, getStructures() {
  3175. console.log('getStructures');
  3176. }
  3177. });
  3178. for (let i = 0; i < 20; i++) {
  3179. var serialized = packr.pack(data);
  3180. var deserialized = packr.unpack(serialized, {lazy: true});
  3181. var copied = {};
  3182. for (let key in deserialized) {
  3183. copied[key] = deserialized[key];
  3184. }
  3185. assert.deepEqual(copied, data);
  3186. }
  3187. });
  3188. test('pack/unpack sample data with bundled strings ' + snippet, function () {
  3189. var data = sampleData;
  3190. let packr = new Packr({ /*structures,*/ useRecords: false, bundleStrings: true});
  3191. var serialized = packr.pack(data);
  3192. var deserialized = packr.unpack(serialized);
  3193. assert.deepEqual(deserialized, data);
  3194. });
  3195. }
  3196. test('pack/unpack sample data with useRecords function', function () {
  3197. var data = [
  3198. {id: 1, type: 1, labels: {a: 1, b: 2}},
  3199. {id: 2, type: 1, labels: {b: 1, c: 2}},
  3200. {id: 3, type: 1, labels: {d: 1, e: 2}}
  3201. ];
  3202. var alternatives = [
  3203. {useRecords: false}, // 88 bytes
  3204. {useRecords: true}, // 58 bytes
  3205. {mapsAsObjects: true, useRecords: (v)=>!!v.id}, // 55 bytes
  3206. {mapsAsObjects: true, variableMapSize: true, useRecords: (v)=>!!v.id} // 49 bytes
  3207. ];
  3208. for(let o of alternatives) {
  3209. let packr = new Packr(o);
  3210. var serialized = packr.pack(data);
  3211. var deserialized = packr.unpack(serialized);
  3212. assert.deepEqual(deserialized, data);
  3213. }
  3214. });
  3215. test('mapAsEmptyObject combination', function () {
  3216. const msgpackr = new Packr({ useRecords: false, encodeUndefinedAsNil: true, variableMapSize: true, mapAsEmptyObject: true, setAsEmptyObject: true });
  3217. const map = new Map();
  3218. map.set('a', 1);
  3219. map.set('b', 2);
  3220. const set = new Set();
  3221. set.add('a');
  3222. set.add('b');
  3223. const input = { map, set };
  3224. const packed = msgpackr.pack(input);
  3225. const unpacked = msgpackr.unpack(packed);
  3226. assert.deepEqual(unpacked.map, {});
  3227. assert.deepEqual(unpacked.set, {});
  3228. });
  3229. test('pack/unpack numeric coercible keys', function () {
  3230. var data = { a: 1, 2: 'test', '-3.45': 'test2'};
  3231. let packr = new Packr({variableMapSize: true, coercibleKeyAsNumber: true, useRecords: false});
  3232. var serialized = packr.pack(data);
  3233. var deserialized = packr.unpack(serialized);
  3234. assert.deepEqual(deserialized, data);
  3235. });
  3236. test('pack/unpack empty data with bundled strings', function () {
  3237. var data = {};
  3238. let packr = new Packr({bundleStrings: true});
  3239. var serialized = packr.pack(data);
  3240. var deserialized = packr.unpack(serialized);
  3241. assert.deepEqual(deserialized, data);
  3242. });
  3243. test('pack/unpack large amount of chinese characters', function() {
  3244. const MSGPACK_OPTIONS = {bundleStrings: true};
  3245. const item = {
  3246. message: '你好你好你好你好你好你好你好你好你好', // some Chinese characters
  3247. };
  3248. testSize(100);
  3249. testSize(1000);
  3250. testSize(10000);
  3251. function testSize(size) {
  3252. const list = [];
  3253. for (let i = 0; i < size; i++) {
  3254. list.push({...item});
  3255. }
  3256. const packer = new Packr(MSGPACK_OPTIONS);
  3257. const unpacker = new Unpackr(MSGPACK_OPTIONS);
  3258. const encoded = packer.pack(list);
  3259. const decoded = unpacker.unpack(encoded);
  3260. assert.deepEqual(list, decoded);
  3261. }
  3262. });
  3263. test('pack/unpack sequential data', function () {
  3264. var data = {foo: 1, bar: 2};
  3265. let packr = new Packr({sequential: true});
  3266. let unpackr = new Unpackr({sequential: true});
  3267. var serialized = packr.pack(data);
  3268. var deserialized = unpackr.unpack(serialized);
  3269. assert.deepEqual(deserialized, data);
  3270. var serialized = packr.pack(data);
  3271. var deserialized = unpackr.unpack(serialized);
  3272. assert.deepEqual(deserialized, data);
  3273. });
  3274. test('pack/unpack with bundled strings and sequential', function () {
  3275. const options = {
  3276. bundleStrings: true,
  3277. sequential: true,
  3278. };
  3279. const packer = new Packr(options);
  3280. const unpacker = new Packr(options);
  3281. const data = {data: 42}; // key length >= 4
  3282. unpacker.unpackMultiple(Buffer.concat([
  3283. packer.pack(data),
  3284. packer.pack(data)
  3285. ]));
  3286. });
  3287. if (typeof Buffer != 'undefined')
  3288. test('replace data', function(){
  3289. var data1 = {
  3290. data: [
  3291. { a: 1, name: 'one', type: 'odd', isOdd: true, a: '13 characters' },
  3292. { a: 2, name: 'two', type: 'even', a: '11 characte' },
  3293. { a: 3, name: 'three', type: 'odd', isOdd: true, a: '12 character' },
  3294. { a: 4, name: 'four', type: 'even', a: '9 charact'},
  3295. { a: 5, name: 'five', type: 'odd', isOdd: true, a: '14 characters!' },
  3296. { a: 6, name: 'six', type: 'even', isOdd: null }
  3297. ],
  3298. };
  3299. var data2 = {
  3300. data: [
  3301. { foo: 7, name: 'one', type: 'odd', isOdd: true },
  3302. { foo: 8, name: 'two', type: 'even'},
  3303. { foo: 9, name: 'three', type: 'odd', isOdd: true },
  3304. { foo: 10, name: 'four', type: 'even'},
  3305. { foo: 11, name: 'five', type: 'odd', isOdd: true },
  3306. { foo: 12, name: 'six', type: 'even', isOdd: null }
  3307. ],
  3308. };
  3309. var serialized1 = pack(data1);
  3310. var serialized2 = pack(data2);
  3311. var b = Buffer.alloc(8000);
  3312. serialized1.copy(b);
  3313. var deserialized1 = unpack(b, serialized1.length);
  3314. serialized2.copy(b);
  3315. var deserialized2 = unpack(b, serialized2.length);
  3316. assert.deepEqual(deserialized1, data1);
  3317. assert.deepEqual(deserialized2, data2);
  3318. });
  3319. test('compact 123', function() {
  3320. assert.equal(pack(123).length, 1);
  3321. });
  3322. test('BigInt', function() {
  3323. let packr = new Packr({useBigIntExtension: true});
  3324. let data = {
  3325. a: 3333333333333333333333333333n,
  3326. b: 1234567890123456789012345678901234567890n,
  3327. c: -3333333333333333333333333333n,
  3328. d: -352523523642364364364264264264264264262642642n,
  3329. e: 0xffffffffffffffffffffffffffn,
  3330. f: -0xffffffffffffffffffffffffffn,
  3331. };
  3332. let serialized = packr.pack(data);
  3333. let deserialized = packr.unpack(serialized);
  3334. assert.deepEqual(data, deserialized);
  3335. });
  3336. test('extended class pack/unpack', function(){
  3337. function Extended() {
  3338. }
  3339. Extended.prototype.getDouble = function() {
  3340. return this.value * 2
  3341. };
  3342. var instance = new Extended();
  3343. instance.value = 4;
  3344. instance.string = 'decode this: ᾜ';
  3345. var data = {
  3346. prop1: 'has multi-byte: ᾜ',
  3347. extendedInstance: instance,
  3348. prop2: 'more string',
  3349. num: 3,
  3350. };
  3351. let packr = new Packr();
  3352. addExtension({
  3353. Class: Extended,
  3354. type: 11,
  3355. unpack: function(buffer) {
  3356. let e = new Extended();
  3357. let data = packr.unpack(buffer);
  3358. e.value = data[0];
  3359. e.string = data[1];
  3360. return e
  3361. },
  3362. pack: function(instance) {
  3363. return packr.pack([instance.value, instance.string])
  3364. }
  3365. });
  3366. var serialized = pack(data);
  3367. var deserialized = unpack(serialized);
  3368. assert.deepEqual(data, deserialized);
  3369. assert.equal(deserialized.extendedInstance.getDouble(), 8);
  3370. });
  3371. test('extended Array class read/write', function(){
  3372. var instance = new ExtendArray();
  3373. instance.push(0);
  3374. instance.push(1);
  3375. instance.push(2);
  3376. var data = {
  3377. prop1: 'has multi-byte: ᾜ',
  3378. extendedInstance: instance,
  3379. prop2: 'more string',
  3380. num: 3,
  3381. };
  3382. new Packr();
  3383. addExtension({
  3384. Class: ExtendArray,
  3385. type: 12,
  3386. read: function(data) {
  3387. Object.setPrototypeOf(data, ExtendArray.prototype);
  3388. return data
  3389. },
  3390. write: function(instance) {
  3391. return [...instance]
  3392. }
  3393. });
  3394. var serialized = pack(data);
  3395. var deserialized = unpack(serialized);
  3396. assert.strictEqual(Object.getPrototypeOf(deserialized.extendedInstance), ExtendArray.prototype);
  3397. assert.deepEqual(data, deserialized);
  3398. });
  3399. test('unregistered extended Array class read/write', function(){
  3400. var instance = new ExtendArray2();
  3401. instance.push(0);
  3402. instance.push(1);
  3403. instance.push(2);
  3404. var data = {
  3405. prop1: 'has multi-byte: ᾜ',
  3406. extendedInstance: instance,
  3407. prop2: 'more string',
  3408. num: 3,
  3409. };
  3410. new Packr();
  3411. var serialized = pack(data);
  3412. var deserialized = unpack(serialized);
  3413. assert.strictEqual(Object.getPrototypeOf(deserialized.extendedInstance), Array.prototype);
  3414. assert.deepEqual(data, deserialized);
  3415. });
  3416. test('unregistered extended Object class read/write', function(){
  3417. var instance = new ExtendObject();
  3418. instance.test1 = "string";
  3419. instance.test2 = 3421321;
  3420. var data = {
  3421. prop1: 'has multi-byte: ᾜ',
  3422. extendedInstance: instance,
  3423. prop2: 'more string',
  3424. num: 3,
  3425. };
  3426. new Packr();
  3427. var serialized = pack(data);
  3428. var deserialized = unpack(serialized);
  3429. assert.strictEqual(Object.getPrototypeOf(deserialized.extendedInstance), Object.prototype);
  3430. assert.deepEqual(data, deserialized);
  3431. });
  3432. test('extended class pack/unpack custom size', function(){
  3433. function TestClass() {
  3434. }
  3435. addExtension({
  3436. Class: TestClass,
  3437. type: 0x01,
  3438. pack() {
  3439. return typeof Buffer != 'undefined' ? Buffer.alloc(256) : new Uint8Array(256)
  3440. },
  3441. unpack(data) {
  3442. return data.length
  3443. }
  3444. });
  3445. let result = unpack(pack(new TestClass()));
  3446. assert.equal(result, 256);
  3447. });
  3448. test('extended class read/write', function(){
  3449. function Extended() {
  3450. }
  3451. Extended.prototype.getDouble = function() {
  3452. return this.value * 2
  3453. };
  3454. var instance = new Extended();
  3455. instance.value = 4;
  3456. instance.string = 'decode this: ᾜ';
  3457. var data = {
  3458. prop1: 'has multi-byte: ᾜ',
  3459. extendedInstance: instance,
  3460. prop2: 'more string',
  3461. num: 3,
  3462. };
  3463. new Packr();
  3464. addExtension({
  3465. Class: Extended,
  3466. type: 12,
  3467. read: function(data) {
  3468. let e = new Extended();
  3469. e.value = data[0];
  3470. e.string = data[1];
  3471. return e
  3472. },
  3473. write: function(instance) {
  3474. return [instance.value, instance.string]
  3475. }
  3476. });
  3477. var serialized = pack(data);
  3478. var deserialized = unpack(serialized);
  3479. assert.deepEqual(data, deserialized);
  3480. assert.equal(deserialized.extendedInstance.getDouble(), 8);
  3481. });
  3482. test('extended class return self', function(){
  3483. function Extended() {
  3484. }
  3485. Extended.prototype.getDouble = function() {
  3486. return this.value * 2
  3487. };
  3488. var instance = new Extended();
  3489. instance.value = 4;
  3490. instance.string = 'decode this: ᾜ';
  3491. var data = {
  3492. prop1: 'has multi-byte: ᾜ',
  3493. extendedInstance: instance,
  3494. prop2: 'more string',
  3495. num: 3,
  3496. };
  3497. new Packr();
  3498. addExtension({
  3499. Class: Extended,
  3500. type: 13,
  3501. read: function(data) {
  3502. Object.setPrototypeOf(data, Extended.prototype);
  3503. return data
  3504. },
  3505. write: function(data) {
  3506. return data
  3507. }
  3508. });
  3509. var serialized = pack(data);
  3510. var deserialized = unpack(serialized);
  3511. assert.deepEqual(data, deserialized);
  3512. assert.strictEqual(Object.getPrototypeOf(deserialized.extendedInstance), Extended.prototype);
  3513. assert.equal(deserialized.extendedInstance.getDouble(), 8);
  3514. });
  3515. test('extended Array class return self', function(){
  3516. var instance = new ExtendArray3();
  3517. instance.push(0);
  3518. instance.push('has multi-byte: ᾜ');
  3519. var data = {
  3520. prop1: 'has multi-byte: ᾜ',
  3521. extendedInstance: instance,
  3522. prop2: 'more string',
  3523. num: 3,
  3524. };
  3525. new Packr();
  3526. addExtension({
  3527. Class: ExtendArray3,
  3528. type: 14,
  3529. read: function(data) {
  3530. Object.setPrototypeOf(data, ExtendArray3.prototype);
  3531. return data
  3532. },
  3533. write: function(data) {
  3534. return data
  3535. }
  3536. });
  3537. var serialized = pack(data);
  3538. var deserialized = unpack(serialized);
  3539. assert.deepEqual(data, deserialized);
  3540. assert.strictEqual(Object.getPrototypeOf(deserialized.extendedInstance), ExtendArray3.prototype);
  3541. assert.equal(deserialized.extendedInstance[0], 0);
  3542. });
  3543. test('extended class pack/unpack proxied', function(){
  3544. function Extended() {
  3545. }
  3546. Extended.prototype.__call__ = function(){
  3547. return this.value * 4
  3548. };
  3549. Extended.prototype.getDouble = function() {
  3550. return this.value * 2
  3551. };
  3552. var instance = function() { instance.__call__();/* callable stuff */ };
  3553. Object.setPrototypeOf(instance,Extended.prototype);
  3554. instance.value = 4;
  3555. var data = instance;
  3556. let packr = new Packr();
  3557. addExtension({
  3558. Class: Extended,
  3559. type: 15,
  3560. unpack: function(buffer) {
  3561. var e = function() { e.__call__(); };
  3562. Object.setPrototypeOf(e,Extended.prototype);
  3563. e.value = packr.unpack(buffer);
  3564. return e
  3565. },
  3566. pack: function(instance) {
  3567. return packr.pack(instance.value)
  3568. }
  3569. });
  3570. var serialized = pack(data);
  3571. var deserialized = unpack(serialized);
  3572. assert.equal(deserialized.getDouble(), 8);
  3573. });
  3574. test.skip('convert Date to string', function(){
  3575. var data = {
  3576. aDate: new Date(),
  3577. };
  3578. new Packr();
  3579. addExtension({
  3580. Class: Date,
  3581. write(date) {
  3582. return date.toString()
  3583. }
  3584. });
  3585. var serialized = pack(data);
  3586. var deserialized = unpack(serialized);
  3587. assert.equal(deserialized.aDate, data.aDate.toString());
  3588. });
  3589. test('standard pack fails on circular reference with shared structures', function () {
  3590. var data = {};
  3591. data.self = data;
  3592. let structures = [];
  3593. let packr = new Packr({
  3594. structures,
  3595. saveStructures(structures) {
  3596. }
  3597. });
  3598. assert.throws(function () {
  3599. packr.pack(data);
  3600. });
  3601. });
  3602. test('proto handling', function() {
  3603. var objectWithProto = JSON.parse('{"__proto__":{"foo":3}}');
  3604. var decoded = unpack(pack(objectWithProto));
  3605. assert(!decoded.foo);
  3606. var objectsWithProto = [objectWithProto, objectWithProto, objectWithProto, objectWithProto, objectWithProto, objectWithProto];
  3607. let packr = new Packr();
  3608. var decoded = packr.unpack(packr.pack(objectsWithProto));
  3609. for (let object of decoded) {
  3610. assert(!decoded.foo);
  3611. }
  3612. });
  3613. test.skip('text decoder', function() {
  3614. let td = new TextDecoder('ISO-8859-15');
  3615. let b = Buffer.alloc(3);
  3616. for (var i = 0; i < 256; i++) {
  3617. b[0] = i;
  3618. b[1] = 0;
  3619. b[2] = 0;
  3620. let s = td.decode(b);
  3621. if (!require('msgpackr-extract').isOneByte(s)) {
  3622. console.log(i.toString(16), s.length);
  3623. }
  3624. }
  3625. });
  3626. test('moreTyesp: Error with causes', function() {
  3627. const object = {
  3628. error: new Error('test'),
  3629. errorWithCause: new Error('test-1', { cause: new Error('test-2')}),
  3630. };
  3631. const packr = new Packr({
  3632. moreTypes: true,
  3633. });
  3634. const serialized = packr.pack(object);
  3635. const deserialized = packr.unpack(serialized);
  3636. assert.equal(deserialized.error.message, object.error.message);
  3637. assert.equal(deserialized.error.cause, object.error.cause);
  3638. assert.equal(deserialized.errorWithCause.message, object.errorWithCause.message);
  3639. assert.equal(deserialized.errorWithCause.cause.message, object.errorWithCause.cause.message);
  3640. assert.equal(deserialized.errorWithCause.cause.cause, object.errorWithCause.cause.cause);
  3641. });
  3642. test('structured cloning: self reference', function() {
  3643. let object = {
  3644. test: 'string',
  3645. children: [
  3646. { name: 'child' }
  3647. ],
  3648. value: new ArrayBuffer(10)
  3649. };
  3650. let u8 = new Uint8Array(object.value);
  3651. u8[0] = 1;
  3652. u8[1] = 2;
  3653. object.self = object;
  3654. object.children[1] = object;
  3655. object.children[2] = object.children[0];
  3656. object.childrenAgain = object.children;
  3657. let packr = new Packr({
  3658. moreTypes: true,
  3659. structuredClone: true,
  3660. });
  3661. var serialized = packr.pack(object);
  3662. var deserialized = packr.unpack(serialized);
  3663. assert.equal(deserialized.self, deserialized);
  3664. assert.equal(deserialized.children[0].name, 'child');
  3665. assert.equal(deserialized.children[1], deserialized);
  3666. assert.equal(deserialized.children[0], deserialized.children[2]);
  3667. assert.equal(deserialized.children, deserialized.childrenAgain);
  3668. assert.equal(deserialized.value.constructor.name, 'ArrayBuffer');
  3669. u8 = new Uint8Array(deserialized.value);
  3670. assert.equal(u8[0], 1);
  3671. assert.equal(u8[1], 2);
  3672. });
  3673. test('structured cloning: types', function() {
  3674. let b = typeof Buffer != 'undefined' ? Buffer.alloc(20) : new Uint8Array(20);
  3675. let fa = new Float32Array(b.buffer, 8, 2);
  3676. fa[0] = 2.25;
  3677. fa[1] = 6;
  3678. let object = {
  3679. error: new Error('test'),
  3680. set: new Set(['a', 'b']),
  3681. regexp: /test/gi,
  3682. float32Array: fa,
  3683. uint16Array: new Uint16Array([3,4])
  3684. };
  3685. let packr = new Packr({
  3686. moreTypes: true,
  3687. structuredClone: true,
  3688. });
  3689. var serialized = packr.pack(object);
  3690. var deserialized = packr.unpack(serialized);
  3691. assert.deepEqual(Array.from(deserialized.set), Array.from(object.set));
  3692. assert.equal(deserialized.error.message, object.error.message);
  3693. assert.equal(deserialized.regexp.test('TEST'), true);
  3694. assert.equal(deserialized.float32Array.constructor.name, 'Float32Array');
  3695. assert.equal(deserialized.float32Array[0], 2.25);
  3696. assert.equal(deserialized.float32Array[1], 6);
  3697. assert.equal(deserialized.uint16Array.constructor.name, 'Uint16Array');
  3698. assert.equal(deserialized.uint16Array[0], 3);
  3699. assert.equal(deserialized.uint16Array[1], 4);
  3700. });
  3701. test('big bundledStrings', function() {
  3702. const MSGPACK_OPTIONS = {bundleStrings: true};
  3703. const packer = new Packr(MSGPACK_OPTIONS);
  3704. const unpacker = new Unpackr(MSGPACK_OPTIONS);
  3705. const payload = {
  3706. output: [
  3707. {
  3708. url: 'https://www.example.com/',
  3709. },
  3710. ],
  3711. };
  3712. for (let i = 0; i < 10000; i++) {
  3713. payload.output.push(payload.output[0]);
  3714. }
  3715. let deserialized = unpacker.unpack(packer.pack(payload));
  3716. assert.equal(deserialized.output[0].url, payload.output[0].url);
  3717. });
  3718. test('structured clone with bundled strings', function() {
  3719. const packer = new Packr({
  3720. structuredClone: true, // both options must be enabled
  3721. bundleStrings: true,
  3722. });
  3723. const v = {};
  3724. let shared = {
  3725. name1: v,
  3726. name2: v,
  3727. };
  3728. let deserialized = packer.unpack(packer.pack(shared));
  3729. assert.equal(deserialized.name1, deserialized.name2);
  3730. shared = {};
  3731. shared.aaaa = shared; // key length >= 4
  3732. deserialized = packer.unpack(packer.pack(shared));
  3733. assert.equal(deserialized.aaaa, deserialized);
  3734. });
  3735. test('object without prototype', function(){
  3736. var data = Object.create(null);
  3737. data.test = 3;
  3738. var serialized = pack(data);
  3739. var deserialized = unpack(serialized);
  3740. assert.deepEqual(deserialized, data);
  3741. });
  3742. test('object with __proto__', function(){
  3743. const data = { foo: 'bar', __proto__: { isAdmin: true } };
  3744. var serialized = pack(data);
  3745. var deserialized = unpack(serialized);
  3746. assert.deepEqual(deserialized, { foo: 'bar' });
  3747. });
  3748. test('separate instances', function() {
  3749. const packr = new Packr({
  3750. structures: [['m', 'e'], ['action', 'share']]
  3751. });
  3752. const packr2 = new Packr({
  3753. structures: [['m', 'e'], ['action', 'share']]
  3754. });
  3755. let packed = packr.pack([{m: 1, e: 2}, {action: 3, share: 4}]);
  3756. // also tried directly decoding this without the first Packr instance packed = new Uint8Array([0x92, 0x40, 0x01, 0x02, 0x41, 0x03, 0x04]);
  3757. console.log(packr2.unpack(packed));
  3758. });
  3759. test('many shared structures', function() {
  3760. let data = [];
  3761. for (let i = 0; i < 200; i++) {
  3762. data.push({['a' + i]: i});
  3763. }
  3764. let structures = [];
  3765. let savedStructures;
  3766. let packr = new Packr({
  3767. structures,
  3768. saveStructures(structures) {
  3769. savedStructures = structures;
  3770. }
  3771. });
  3772. var serializedWith32 = packr.pack(data);
  3773. assert.equal(savedStructures.length, 32);
  3774. var deserialized = packr.unpack(serializedWith32);
  3775. assert.deepEqual(deserialized, data);
  3776. structures = structures.slice(0, 32);
  3777. packr = new Packr({
  3778. structures,
  3779. maxSharedStructures: 100,
  3780. saveStructures(structures) {
  3781. savedStructures = structures;
  3782. }
  3783. });
  3784. deserialized = packr.unpack(serializedWith32);
  3785. assert.deepEqual(deserialized, data);
  3786. structures = structures.slice(0, 32);
  3787. packr = new Packr({
  3788. structures,
  3789. maxSharedStructures: 100,
  3790. saveStructures(structures) {
  3791. savedStructures = structures;
  3792. }
  3793. });
  3794. let serialized = packr.pack(data);
  3795. assert.equal(savedStructures.length, 100);
  3796. deserialized = packr.unpack(serialized);
  3797. assert.deepEqual(deserialized, data);
  3798. deserialized = packr.unpack(serializedWith32);
  3799. assert.deepEqual(deserialized, data);
  3800. assert.equal(savedStructures.length, 100);
  3801. deserialized = packr.unpack(serialized);
  3802. assert.deepEqual(deserialized, data);
  3803. assert.equal(packr.structures.sharedLength, 100);
  3804. });
  3805. test('more shared structures', function() {
  3806. const structures = [];
  3807. for (let i = 0; i < 40; i++) {
  3808. structures.push(['a' + i]);
  3809. }
  3810. const structures2 = [...structures];
  3811. const packr = new Packr({
  3812. getStructures() {
  3813. return structures
  3814. },
  3815. saveStructures(structures) {
  3816. },
  3817. maxSharedStructures: 100
  3818. });
  3819. const packr2 = new Packr({
  3820. getStructures() {
  3821. return structures2
  3822. },
  3823. saveStructures(structures) {
  3824. },
  3825. maxSharedStructures: 100
  3826. });
  3827. const inputData = {a35: 35};
  3828. const buffer = packr.pack(inputData);
  3829. const outputData = packr2.decode(buffer);
  3830. assert.deepEqual(inputData, outputData);
  3831. });
  3832. test('big buffer', function() {
  3833. var size = 100000000;
  3834. var data = new Uint8Array(size).fill(1);
  3835. var packed = pack(data);
  3836. var unpacked = unpack(packed);
  3837. assert.equal(unpacked.length, size);
  3838. });
  3839. test('random strings', function(){
  3840. var data = [];
  3841. for (var i = 0; i < 2000; i++) {
  3842. var str = 'test';
  3843. while (Math.random() < 0.7 && str.length < 0x100000) {
  3844. str = str + String.fromCharCode(90/(Math.random() + 0.01)) + str;
  3845. }
  3846. data.push(str);
  3847. }
  3848. var serialized = pack(data);
  3849. var deserialized = unpack(serialized);
  3850. assert.deepEqual(deserialized, data);
  3851. });
  3852. test('map/date', function(){
  3853. var map = new Map();
  3854. map.set(4, 'four');
  3855. map.set('three', 3);
  3856. var data = {
  3857. map: map,
  3858. date: new Date(1532219539733),
  3859. farFutureDate: new Date(3532219539133),
  3860. fartherFutureDate: new Date('2106-08-05T18:48:20.323Z'),
  3861. ancient: new Date(-3532219539133),
  3862. invalidDate: new Date('invalid')
  3863. };
  3864. let packr = new Packr();
  3865. var serialized = packr.pack(data);
  3866. var deserialized = packr.unpack(serialized);
  3867. assert.equal(deserialized.map.get(4), 'four');
  3868. assert.equal(deserialized.map.get('three'), 3);
  3869. assert.equal(deserialized.date.getTime(), 1532219539733);
  3870. assert.equal(deserialized.farFutureDate.getTime(), 3532219539133);
  3871. assert.equal(deserialized.fartherFutureDate.toISOString(), '2106-08-05T18:48:20.323Z');
  3872. assert.equal(deserialized.ancient.getTime(), -3532219539133);
  3873. assert.equal(deserialized.invalidDate.toString(), 'Invalid Date');
  3874. });
  3875. test('map/date with options', function(){
  3876. var map = new Map();
  3877. map.set(4, 'four');
  3878. map.set('three', 3);
  3879. var data = {
  3880. map: map,
  3881. date: new Date(1532219539011),
  3882. invalidDate: new Date('invalid')
  3883. };
  3884. let packr = new Packr({
  3885. mapsAsObjects: true,
  3886. useTimestamp32: true,
  3887. onInvalidDate: () => 'Custom invalid date'
  3888. });
  3889. var serialized = packr.pack(data);
  3890. var deserialized = packr.unpack(serialized);
  3891. assert.equal(deserialized.map[4], 'four');
  3892. assert.equal(deserialized.map.three, 3);
  3893. assert.equal(deserialized.date.getTime(), 1532219539000);
  3894. assert.equal(deserialized.invalidDate, 'Custom invalid date');
  3895. });
  3896. test('key caching', function() {
  3897. var data = {
  3898. foo: 2,
  3899. bar: 'test',
  3900. four: 4,
  3901. seven: 7,
  3902. foz: 3,
  3903. };
  3904. var serialized = pack(data);
  3905. var deserialized = unpack(serialized);
  3906. assert.deepEqual(deserialized, data);
  3907. // do multiple times to test caching
  3908. var serialized = pack(data);
  3909. var deserialized = unpack(serialized);
  3910. assert.deepEqual(deserialized, data);
  3911. var serialized = pack(data);
  3912. var deserialized = unpack(serialized);
  3913. assert.deepEqual(deserialized, data);
  3914. });
  3915. test('strings', function() {
  3916. var data = [''];
  3917. var serialized = pack(data);
  3918. var deserialized = unpack(serialized);
  3919. assert.deepEqual(deserialized, data);
  3920. // do multiple times
  3921. var serialized = pack(data);
  3922. var deserialized = unpack(serialized);
  3923. assert.deepEqual(deserialized, data);
  3924. data = 'decode this: ᾜ';
  3925. var serialized = pack(data);
  3926. var deserialized = unpack(serialized);
  3927. assert.deepEqual(deserialized, data);
  3928. data = 'decode this that is longer but without any non-latin characters';
  3929. var serialized = pack(data);
  3930. var deserialized = unpack(serialized);
  3931. assert.deepEqual(deserialized, data);
  3932. });
  3933. test('decimal float32', function() {
  3934. var data = {
  3935. a: 2.526,
  3936. b: 0.0035235,
  3937. c: 0.00000000000352501,
  3938. d: 3252.77,
  3939. };
  3940. let packr = new Packr({
  3941. useFloat32: DECIMAL_FIT
  3942. });
  3943. var serialized = packr.pack(data);
  3944. assert.equal(serialized.length, 32);
  3945. var deserialized = packr.unpack(serialized);
  3946. assert.deepEqual(deserialized, data);
  3947. });
  3948. test('int64/uint64 should be bigints by default', function() {
  3949. var data = {
  3950. a: 325283295382932843n
  3951. };
  3952. let packr = new Packr();
  3953. var serialized = packr.pack(data);
  3954. var deserialized = packr.unpack(serialized);
  3955. assert.deepEqual(deserialized.a, 325283295382932843n);
  3956. });
  3957. test('bigint to float', function() {
  3958. var data = {
  3959. a: 325283295382932843n
  3960. };
  3961. let packr = new Packr({
  3962. int64AsType: 'number'
  3963. });
  3964. var serialized = packr.pack(data);
  3965. var deserialized = packr.unpack(serialized);
  3966. assert.deepEqual(deserialized.a, 325283295382932843);
  3967. });
  3968. test('int64AsNumber compatibility', function() {
  3969. // https://github.com/kriszyp/msgpackr/pull/85
  3970. var data = {
  3971. a: 325283295382932843n
  3972. };
  3973. let packr = new Packr({
  3974. int64AsNumber: true
  3975. });
  3976. var serialized = packr.pack(data);
  3977. var deserialized = packr.unpack(serialized);
  3978. assert.deepEqual(deserialized.a, 325283295382932843);
  3979. });
  3980. test('bigint to auto (float or bigint)', function() {
  3981. var data = {
  3982. a: -9007199254740993n,
  3983. b: -9007199254740992n,
  3984. c: 0n,
  3985. d: 9007199254740992n,
  3986. e: 9007199254740993n,
  3987. };
  3988. let packr = new Packr({
  3989. int64AsType: 'auto'
  3990. });
  3991. var serialized = packr.pack(data);
  3992. var deserialized = packr.unpack(serialized);
  3993. assert.deepEqual(deserialized.a, -9007199254740993n);
  3994. assert.deepEqual(deserialized.b, -9007199254740992);
  3995. assert.deepEqual(deserialized.c, 0);
  3996. assert.deepEqual(deserialized.d, 9007199254740992);
  3997. assert.deepEqual(deserialized.e, 9007199254740993n);
  3998. });
  3999. test('bigint to string', function() {
  4000. var data = {
  4001. a: 325283295382932843n,
  4002. };
  4003. let packr = new Packr({
  4004. int64AsType: 'string'
  4005. });
  4006. var serialized = packr.pack(data);
  4007. var deserialized = packr.unpack(serialized);
  4008. assert.deepEqual(deserialized.a, '325283295382932843');
  4009. });
  4010. test('fixint should be one byte', function(){
  4011. let encoded = pack(123);
  4012. assert.equal(encoded.length, 1);
  4013. });
  4014. test('numbers', function(){
  4015. var data = {
  4016. bigEncodable: 48978578104322,
  4017. dateEpoch: 1530886513200,
  4018. realBig: 3432235352353255323,
  4019. decimal: 32.55234,
  4020. negative: -34.11,
  4021. exponential: 0.234e123,
  4022. tiny: 3.233e-120,
  4023. zero: 0,
  4024. //negativeZero: -0,
  4025. Infinity: Infinity
  4026. };
  4027. var serialized = pack(data);
  4028. var deserialized = unpack(serialized);
  4029. assert.deepEqual(deserialized, data);
  4030. });
  4031. test('bigint', function(){
  4032. var data = {
  4033. bigintSmall: 352n,
  4034. bigintSmallNegative: -333335252n,
  4035. bigintBig: 2n**64n - 1n, // biggest possible
  4036. bigintBigNegative: -(2n**63n), // largest negative
  4037. mixedWithNormal: 44,
  4038. };
  4039. var serialized = pack(data);
  4040. var deserialized = unpack(serialized);
  4041. assert.deepEqual(deserialized, data);
  4042. var tooBigInt = {
  4043. tooBig: 2n**66n
  4044. };
  4045. assert.throws(function(){ serialized = pack(tooBigInt); });
  4046. let packr = new Packr({
  4047. largeBigIntToFloat: true
  4048. });
  4049. serialized = packr.pack(tooBigInt);
  4050. deserialized = unpack(serialized);
  4051. assert.isTrue(deserialized.tooBig > 2n**65n);
  4052. packr = new Packr({
  4053. largeBigIntToString: true
  4054. });
  4055. serialized = packr.pack(tooBigInt);
  4056. deserialized = unpack(serialized);
  4057. assert.equal(deserialized.tooBig, (2n**66n).toString());
  4058. });
  4059. test('roundFloat32', function() {
  4060. assert.equal(roundFloat32(0.00333000003), 0.00333);
  4061. assert.equal(roundFloat32(43.29999999993), 43.3);
  4062. });
  4063. test('buffers', function(){
  4064. var data = {
  4065. buffer1: new Uint8Array([2,3,4]),
  4066. buffer2: new Uint8Array(pack(sampleData))
  4067. };
  4068. var serialized = pack(data);
  4069. var deserialized = unpack(serialized);
  4070. assert.deepEqual(deserialized, data);
  4071. });
  4072. test('notepack test', function() {
  4073. const data = {
  4074. foo: 1,
  4075. bar: [1, 2, 3, 4, 'abc', 'def'],
  4076. foobar: {
  4077. foo: true,
  4078. bar: -2147483649,
  4079. foobar: {
  4080. foo: new Uint8Array([1, 2, 3, 4, 5]),
  4081. bar: 1.5,
  4082. foobar: [true, false, 'abcdefghijkmonpqrstuvwxyz']
  4083. }
  4084. }
  4085. };
  4086. var serialized = pack(data);
  4087. var deserialized = unpack(serialized);
  4088. var deserialized = unpack(serialized);
  4089. var deserialized = unpack(serialized);
  4090. assert.deepEqual(deserialized, data);
  4091. });
  4092. test('utf16 causing expansion', function() {
  4093. this.timeout(10000);
  4094. let data = {fixstr: 'ᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝ', str8:'ᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝ'};
  4095. var serialized = pack(data);
  4096. var deserialized = unpack(serialized);
  4097. assert.deepEqual(deserialized, data);
  4098. });
  4099. test('unpackMultiple', () => {
  4100. let values = unpackMultiple(new Uint8Array([1, 2, 3, 4]));
  4101. assert.deepEqual(values, [1, 2, 3, 4]);
  4102. values = [];
  4103. unpackMultiple(new Uint8Array([1, 2, 3, 4]), value => values.push(value));
  4104. assert.deepEqual(values, [1, 2, 3, 4]);
  4105. });
  4106. test('unpackMultiple with positions', () => {
  4107. let values = unpackMultiple(new Uint8Array([1, 2, 3, 4]));
  4108. assert.deepEqual(values, [1, 2, 3, 4]);
  4109. values = [];
  4110. unpackMultiple(new Uint8Array([1, 2, 3, 4]), (value,start,end) => values.push([value,start,end]));
  4111. assert.deepEqual(values, [[1,0,1], [2,1,2], [3,2,3], [4,3,4]]);
  4112. });
  4113. test('pack toJSON returning this', () => {
  4114. class Serializable {
  4115. someData = [1, 2, 3, 4]
  4116. toJSON() {
  4117. return this
  4118. }
  4119. }
  4120. const serialized = pack(new Serializable);
  4121. const deserialized = unpack(serialized);
  4122. assert.deepStrictEqual(deserialized, { someData: [1, 2, 3, 4] });
  4123. });
  4124. test('skip values', function () {
  4125. var data = {
  4126. data: [
  4127. { a: 1, name: 'one', type: 'odd', isOdd: true },
  4128. { a: 2, name: 'two', type: 'even', isOdd: undefined },
  4129. { a: 3, name: 'three', type: 'odd', isOdd: true },
  4130. { a: 4, name: 'four', type: 'even', isOdd: null},
  4131. { a: 5, name: 'five', type: 'odd', isOdd: true },
  4132. { a: 6, name: 'six', type: 'even', isOdd: null }
  4133. ],
  4134. description: 'some names',
  4135. types: ['odd', 'even'],
  4136. convertEnumToNum: [
  4137. { prop: 'test' },
  4138. { prop: 'test' },
  4139. { prop: 'test' },
  4140. { prop: 1 },
  4141. { prop: 2 },
  4142. { prop: [undefined, null] },
  4143. { prop: null }
  4144. ]
  4145. };
  4146. var expected = {
  4147. data: [
  4148. { a: 1, name: 'one', type: 'odd', isOdd: true },
  4149. { a: 2, name: 'two', type: 'even' },
  4150. { a: 3, name: 'three', type: 'odd', isOdd: true },
  4151. { a: 4, name: 'four', type: 'even', },
  4152. { a: 5, name: 'five', type: 'odd', isOdd: true },
  4153. { a: 6, name: 'six', type: 'even' }
  4154. ],
  4155. description: 'some names',
  4156. types: ['odd', 'even'],
  4157. convertEnumToNum: [
  4158. { prop: 'test' },
  4159. { prop: 'test' },
  4160. { prop: 'test' },
  4161. { prop: 1 },
  4162. { prop: 2 },
  4163. { prop: [undefined, null] },
  4164. {}
  4165. ]
  4166. };
  4167. let packr = new Packr({ useRecords: false, skipValues: [undefined, null] });
  4168. var serialized = packr.pack(data);
  4169. var deserialized = packr.unpack(serialized);
  4170. assert.deepEqual(deserialized, expected);
  4171. });
  4172. });
  4173. suite('msgpackr performance tests', function(){
  4174. test('performance JSON.parse', function() {
  4175. var data = sampleData;
  4176. this.timeout(10000);
  4177. var serialized = JSON.stringify(data);
  4178. console.log('JSON size', serialized.length);
  4179. for (var i = 0; i < ITERATIONS; i++) {
  4180. JSON.parse(serialized);
  4181. }
  4182. });
  4183. test('performance JSON.stringify', function() {
  4184. var data = sampleData;
  4185. this.timeout(10000);
  4186. for (var i = 0; i < ITERATIONS; i++) {
  4187. JSON.stringify(data);
  4188. }
  4189. });
  4190. test('performance unpack', function() {
  4191. var data = sampleData;
  4192. this.timeout(10000);
  4193. let structures = [];
  4194. var serialized = pack(data);
  4195. console.log('MessagePack size', serialized.length);
  4196. let packr = new Packr({ structures, bundleStrings: false });
  4197. var serialized = packr.pack(data);
  4198. console.log('msgpackr w/ record ext size', serialized.length);
  4199. for (var i = 0; i < ITERATIONS; i++) {
  4200. packr.unpack(serialized);
  4201. }
  4202. });
  4203. test('performance pack', function() {
  4204. var data = sampleData;
  4205. this.timeout(10000);
  4206. let structures = [];
  4207. let packr = new Packr({ structures, bundleStrings: false });
  4208. let buffer = typeof Buffer != 'undefined' ? Buffer.alloc(0x10000) : new Uint8Array(0x10000);
  4209. for (var i = 0; i < ITERATIONS; i++) {
  4210. //serialized = pack(data, { shared: sharedStructure })
  4211. packr.useBuffer(buffer);
  4212. packr.pack(data);
  4213. //var serializedGzip = deflateSync(serialized)
  4214. }
  4215. //console.log('serialized', serialized.length, global.propertyComparisons)
  4216. });
  4217. });
  4218. })(chai, null, module, fs);
  4219. //# sourceMappingURL=test.js.map