This is an automated email from the ASF dual-hosted git repository.

wangweipeng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git


The following commit(s) were added to refs/heads/main by this push:
     new c93e6ee43 feat(JavaScript):  Align xlang protocol (#3326)
c93e6ee43 is described below

commit c93e6ee43e65226210137e92f4c6913207c88351
Author: weipeng <[email protected]>
AuthorDate: Wed Feb 11 23:03:02 2026 +0800

    feat(JavaScript):  Align xlang protocol (#3326)
    
    ## Why?
    1. Align xlang protocol. current progress is 38/39
    
    
    ## What does this PR do?
    
    
    
    ## Related issues
    #3133
    
    
    ## Does this PR introduce any user-facing change?
    
    
    
    - [ ] Does this PR introduce any public API change?
    - [ ] Does this PR introduce any binary protocol compatibility change?
    
    ## Benchmark
---
 javascript/packages/fory/lib/gen/any.ts          |   2 +-
 javascript/packages/fory/lib/gen/binary.ts       |  58 -----
 javascript/packages/fory/lib/gen/builder.ts      |   8 +-
 javascript/packages/fory/lib/gen/datetime.ts     |  65 +++---
 javascript/packages/fory/lib/gen/enum.ts         |   6 +
 javascript/packages/fory/lib/gen/index.ts        |   3 +-
 javascript/packages/fory/lib/gen/typedArray.ts   | 124 ++++++++---
 javascript/packages/fory/lib/meta/TypeMeta.ts    |  11 +-
 javascript/packages/fory/lib/typeInfo.ts         |  19 +-
 javascript/packages/fory/lib/typeMetaResolver.ts |  16 +-
 javascript/packages/fory/lib/typeResolver.ts     |  33 ++-
 javascript/packages/fory/lib/writer/index.ts     |   6 +
 javascript/test/array.test.ts                    |  22 +-
 javascript/test/crossLanguage.test.ts            | 267 +++++++++++++++++++----
 javascript/test/datetime.test.ts                 |   7 +-
 javascript/test/fory.test.ts                     |   2 +-
 javascript/test/object.test.ts                   |   2 +-
 17 files changed, 461 insertions(+), 190 deletions(-)

diff --git a/javascript/packages/fory/lib/gen/any.ts 
b/javascript/packages/fory/lib/gen/any.ts
index b3dd6aa88..cf941ca60 100644
--- a/javascript/packages/fory/lib/gen/any.ts
+++ b/javascript/packages/fory/lib/gen/any.ts
@@ -37,7 +37,7 @@ export class AnyHelper {
 
     function tryUpdateSerializer(serializer: Serializer | undefined | null, 
typeMeta: TypeMeta) {
       if (!serializer) {
-        throw new Error(`can't find implements of typeId: ${typeId}`);
+        return fory.typeMetaResolver.genSerializerByTypeMetaRuntime(typeMeta);
       }
       const hash = serializer.getHash();
       if (hash !== typeMeta.getHash()) {
diff --git a/javascript/packages/fory/lib/gen/binary.ts 
b/javascript/packages/fory/lib/gen/binary.ts
deleted file mode 100644
index f44f63302..000000000
--- a/javascript/packages/fory/lib/gen/binary.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { TypeInfo } from "../typeInfo";
-import { CodecBuilder } from "./builder";
-import { BaseSerializerGenerator } from "./serializer";
-import { CodegenRegistry } from "./router";
-import { TypeId } from "../type";
-import { Scope } from "./scope";
-
-class BinarySerializerGenerator extends BaseSerializerGenerator {
-  typeInfo: TypeInfo;
-
-  constructor(typeInfo: TypeInfo, builder: CodecBuilder, scope: Scope) {
-    super(typeInfo, builder, scope);
-    this.typeInfo = typeInfo;
-  }
-
-  write(accessor: string): string {
-    return `
-        ${this.builder.writer.uint8(1)}
-        ${this.builder.writer.uint32(`${accessor}.byteLength`)}
-        ${this.builder.writer.buffer(accessor)}
-        `;
-  }
-
-  read(accessor: (expr: string) => string, refState: string): string {
-    const result = this.scope.uniqueName("result");
-    return `
-        ${this.builder.reader.uint8()}
-        ${result} = ${this.builder.reader.buffer(this.builder.reader.int32())};
-        ${this.maybeReference(result, refState)};
-        ${accessor(result)}
-        `;
-  }
-
-  getFixedSize(): number {
-    return 8;
-  }
-}
-
-CodegenRegistry.register(TypeId.BINARY, BinarySerializerGenerator);
diff --git a/javascript/packages/fory/lib/gen/builder.ts 
b/javascript/packages/fory/lib/gen/builder.ts
index 8138220f4..7627340d1 100644
--- a/javascript/packages/fory/lib/gen/builder.ts
+++ b/javascript/packages/fory/lib/gen/builder.ts
@@ -79,8 +79,8 @@ export class BinaryReaderBuilder {
     return `${this.holder}.buffer(${len})`;
   }
 
-  bufferRef() {
-    return `${this.holder}.bufferRef()`;
+  bufferRef(len: string | number) {
+    return `${this.holder}.bufferRef(${len})`;
   }
 
   uint8() {
@@ -177,6 +177,10 @@ class BinaryWriterBuilder {
     return `${this.holder}.reserve(${v})`;
   }
 
+  arrayBuffer(buffer: number | string, byteOffset: number | string, 
byteLength: number | string) {
+    return `${this.holder}.arrayBuffer(${buffer}, ${byteOffset}, 
${byteLength})`;
+  }
+
   uint16(v: number | string) {
     return `${this.holder}.uint16(${v})`;
   }
diff --git a/javascript/packages/fory/lib/gen/datetime.ts 
b/javascript/packages/fory/lib/gen/datetime.ts
index 6a32de666..071e7c3d2 100644
--- a/javascript/packages/fory/lib/gen/datetime.ts
+++ b/javascript/packages/fory/lib/gen/datetime.ts
@@ -33,32 +33,16 @@ class TimestampSerializerGenerator extends 
BaseSerializerGenerator {
   }
 
   write(accessor: string): string {
-    if (/^-?[0-9]+$/.test(accessor)) {
-      const msVar = this.scope.uniqueName("ts_ms");
-      const secondsVar = this.scope.uniqueName("ts_sec");
-      const nanosVar = this.scope.uniqueName("ts_nanos");
-      return `
-            {
-              const ${msVar} = ${accessor};
-              const ${secondsVar} = Math.floor(${msVar} / 1000);
-              const ${nanosVar} = (${msVar} - ${secondsVar} * 1000) * 1000000;
-              ${this.builder.writer.int64(`BigInt(${secondsVar})`)}
-              ${this.builder.writer.uint32(`${nanosVar}`)}
-            }
-        `;
-    }
     const msVar = this.scope.uniqueName("ts_ms");
     const secondsVar = this.scope.uniqueName("ts_sec");
     const nanosVar = this.scope.uniqueName("ts_nanos");
     return `
-            {
-              const ${msVar} = ${accessor}.getTime();
-              const ${secondsVar} = Math.floor(${msVar} / 1000);
-              const ${nanosVar} = (${msVar} - ${secondsVar} * 1000) * 1000000;
-              ${this.builder.writer.int64(`BigInt(${secondsVar})`)}
-              ${this.builder.writer.uint32(`${nanosVar}`)}
-            }
-        `;
+      const ${msVar} = (${accessor} instanceof Date) ? ${accessor}.getTime() : 
${accessor};
+      const ${secondsVar} = Math.floor(${msVar} / 1000);
+      const ${nanosVar} = (${msVar} - ${secondsVar} * 1000) * 1000000;
+      ${this.builder.writer.int64(`${secondsVar}`)}
+      ${this.builder.writer.uint32(`${nanosVar}`)}
+      `;
   }
 
   read(accessor: (expr: string) => string): string {
@@ -80,6 +64,38 @@ class DurationSerializerGenerator extends 
BaseSerializerGenerator {
     this.typeInfo = typeInfo;
   }
 
+  write(accessor: string): string {
+    const msVar = this.scope.uniqueName("ts_ms");
+    const secondsVar = this.scope.uniqueName("ts_sec");
+    const nanosVar = this.scope.uniqueName("ts_nanos");
+    return `
+      const ${msVar} = ${accessor};
+      const ${secondsVar} = Math.floor(${msVar} / 1000);
+      const ${nanosVar} = (${msVar} - ${secondsVar} * 1000) * 1000000;
+      ${this.builder.writer.int64(`${secondsVar}`)}
+      ${this.builder.writer.uint32(`${nanosVar}`)}
+      `;
+  }
+
+  read(accessor: (expr: string) => string): string {
+    const seconds = this.builder.reader.int64();
+    const nanos = this.builder.reader.uint32();
+    return accessor(`Number(${seconds}) * 1000 + Math.floor(${nanos} / 
1000000)`);
+  }
+
+  getFixedSize(): number {
+    return 7;
+  }
+}
+
+class DateSerializerGenerator extends BaseSerializerGenerator {
+  typeInfo: TypeInfo;
+
+  constructor(typeInfo: TypeInfo, builder: CodecBuilder, scope: Scope) {
+    super(typeInfo, builder, scope);
+    this.typeInfo = typeInfo;
+  }
+
   write(accessor: string): string {
     const epoch = this.scope.declareByName("epoch", `new Date("1970/01/01 
00:00").getTime()`);
     return `
@@ -93,9 +109,7 @@ class DurationSerializerGenerator extends 
BaseSerializerGenerator {
 
   read(accessor: (expr: string) => string): string {
     const epoch = this.scope.declareByName("epoch", `new Date("1970/01/01 
00:00").getTime()`);
-    return accessor(`
-            new Date(${epoch} + (${this.builder.reader.int32()} * (24 * 60 * 
60) * 1000))
-        `);
+    return accessor(`new Date(${epoch} + (${this.builder.reader.int32()} * (24 
* 60 * 60) * 1000))`);
   }
 
   getFixedSize(): number {
@@ -105,3 +119,4 @@ class DurationSerializerGenerator extends 
BaseSerializerGenerator {
 
 CodegenRegistry.register(TypeId.DURATION, DurationSerializerGenerator);
 CodegenRegistry.register(TypeId.TIMESTAMP, TimestampSerializerGenerator);
+CodegenRegistry.register(TypeId.DATE, DateSerializerGenerator);
diff --git a/javascript/packages/fory/lib/gen/enum.ts 
b/javascript/packages/fory/lib/gen/enum.ts
index 65e289f21..6a7218780 100644
--- a/javascript/packages/fory/lib/gen/enum.ts
+++ b/javascript/packages/fory/lib/gen/enum.ts
@@ -33,6 +33,9 @@ class EnumSerializerGenerator extends BaseSerializerGenerator 
{
   }
 
   write(accessor: string): string {
+    if (!this.typeInfo.options?.inner) {
+      return this.builder.writer.varUInt32(accessor);
+    }
     if (Object.values(this.typeInfo.options.inner).length < 1) {
       throw new Error("An enum must contain at least one field");
     }
@@ -121,6 +124,9 @@ class EnumSerializerGenerator extends 
BaseSerializerGenerator {
   }
 
   read(accessor: (expr: string) => string): string {
+    if (!this.typeInfo.options?.inner) {
+      return accessor(this.builder.reader.varUInt32());
+    }
     const enumValue = this.scope.uniqueName("enum_v");
     return `
         const ${enumValue} = ${this.builder.reader.varUInt32()};
diff --git a/javascript/packages/fory/lib/gen/index.ts 
b/javascript/packages/fory/lib/gen/index.ts
index 64529f060..6df62034e 100644
--- a/javascript/packages/fory/lib/gen/index.ts
+++ b/javascript/packages/fory/lib/gen/index.ts
@@ -25,7 +25,6 @@ import { Scope } from "./scope";
 import "./array";
 import "./struct";
 import "./string";
-import "./binary";
 import "./bool";
 import "./datetime";
 import "./map";
@@ -77,7 +76,7 @@ export class Gen {
         return;
       }
       const options = (<StructTypeInfo>typeInfo).options;
-      if (options.props) {
+      if (options?.props) {
         this.register(<StructTypeInfo>typeInfo);
         Object.values(options.props).forEach((x) => {
           this.traversalContainer(x);
diff --git a/javascript/packages/fory/lib/gen/typedArray.ts 
b/javascript/packages/fory/lib/gen/typedArray.ts
index 6b2f86868..38659a4d7 100644
--- a/javascript/packages/fory/lib/gen/typedArray.ts
+++ b/javascript/packages/fory/lib/gen/typedArray.ts
@@ -19,45 +19,37 @@
 
 import { Type, TypeInfo } from "../typeInfo";
 import { CodecBuilder } from "./builder";
-import { BaseSerializerGenerator, SerializerGenerator } from "./serializer";
+import { BaseSerializerGenerator } from "./serializer";
 import { CodegenRegistry } from "./router";
 import { Scope } from "./scope";
 import { TypeId } from "../type";
 
-function build(inner: TypeInfo) {
+function build(inner: TypeInfo, creator: string, size: number) {
   return class TypedArraySerializerGenerator extends BaseSerializerGenerator {
     typeInfo: TypeInfo;
-    innerGenerator: SerializerGenerator;
 
     constructor(typeInfo: TypeInfo, builder: CodecBuilder, scope: Scope) {
       super(typeInfo, builder, scope);
       this.typeInfo = <TypeInfo>typeInfo;
-      this.innerGenerator = CodegenRegistry.newGeneratorByTypeInfo(inner, 
builder, scope);
     }
 
     write(accessor: string): string {
-      const item = this.scope.uniqueName("item");
       return `
-                ${this.builder.writer.varUInt32(`${accessor}.length`)}
-                
${this.builder.writer.reserve(`${this.innerGenerator.getFixedSize()} * 
${accessor}.length`)};
-                for (const ${item} of ${accessor}) {
-                    ${this.innerGenerator.writeEmbed().write(item)}
-                }
+                ${this.builder.writer.varUInt32(`${accessor}.byteLength`)}
+                ${this.builder.writer.arrayBuffer(`${accessor}.buffer`, 
`${accessor}.byteOffset`, `${accessor}.byteLength`)}
             `;
     }
 
     read(accessor: (expr: string) => string, refState: string): string {
       const result = this.scope.uniqueName("result");
       const len = this.scope.uniqueName("len");
-      const idx = this.scope.uniqueName("idx");
+      const copied = this.scope.uniqueName("copied");
 
       return `
                 const ${len} = ${this.builder.reader.varUInt32()};
-                const ${result} = new Array(${len});
+                const ${copied} = ${this.builder.reader.buffer(len)}
+                const ${result} = new ${creator}(${copied}.buffer, 
${copied}.byteOffset, ${copied}.byteLength / ${size});
                 ${this.maybeReference(result, refState)}
-                for (let ${idx} = 0; ${idx} < ${len}; ${idx}++) {
-                    ${this.innerGenerator.read(x => `${result}[${idx}] = 
${x};`, "false")}
-                }
                 ${accessor(result)}
              `;
     }
@@ -68,15 +60,93 @@ function build(inner: TypeInfo) {
   };
 }
 
-CodegenRegistry.register(TypeId.BOOL_ARRAY, build(Type.bool()));
-CodegenRegistry.register(TypeId.INT8_ARRAY, build(Type.int8()));
-CodegenRegistry.register(TypeId.INT16_ARRAY, build(Type.int16()));
-CodegenRegistry.register(TypeId.INT32_ARRAY, build(Type.int32()));
-CodegenRegistry.register(TypeId.INT64_ARRAY, build(Type.int64()));
-CodegenRegistry.register(TypeId.UINT8_ARRAY, build(Type.uint8()));
-CodegenRegistry.register(TypeId.UINT16_ARRAY, build(Type.uint16()));
-CodegenRegistry.register(TypeId.UINT32_ARRAY, build(Type.uint32()));
-CodegenRegistry.register(TypeId.UINT64_ARRAY, build(Type.uint64()));
-CodegenRegistry.register(TypeId.FLOAT16_ARRAY, build(Type.float16()));
-CodegenRegistry.register(TypeId.FLOAT32_ARRAY, build(Type.float32()));
-CodegenRegistry.register(TypeId.FLOAT64_ARRAY, build(Type.float64()));
+class BoolArraySerializerGenerator extends BaseSerializerGenerator {
+  typeInfo: TypeInfo;
+
+  constructor(typeInfo: TypeInfo, builder: CodecBuilder, scope: Scope) {
+    super(typeInfo, builder, scope);
+    this.typeInfo = <TypeInfo>typeInfo;
+  }
+
+  write(accessor: string): string {
+    const item = this.scope.uniqueName("item");
+    return `
+                ${this.builder.writer.varUInt32(`${accessor}.length`)}
+                ${this.builder.writer.reserve(`${accessor}.length`)};
+                for (const ${item} of ${accessor}) {
+                  ${this.builder.writer.uint8(`${item} ? 1 : 0`)}
+                }
+            `;
+  }
+
+  read(accessor: (expr: string) => string, refState: string): string {
+    const result = this.scope.uniqueName("result");
+    const len = this.scope.uniqueName("len");
+    const idx = this.scope.uniqueName("idx");
+    return `
+                const ${len} = ${this.builder.reader.varUInt32()};
+                const ${result} = new Array(${len});
+                ${this.maybeReference(result, refState)}
+                for (let ${idx} = 0; ${idx} < ${len}; ${idx}++) {
+                  ${result}[${idx}] = ${this.builder.reader.uint8()} === 1;
+                }
+                ${accessor(result)}
+             `;
+  }
+
+  getFixedSize(): number {
+    return 7;
+  }
+}
+
+class Float16ArraySerializerGenerator extends BaseSerializerGenerator {
+  typeInfo: TypeInfo;
+
+  constructor(typeInfo: TypeInfo, builder: CodecBuilder, scope: Scope) {
+    super(typeInfo, builder, scope);
+    this.typeInfo = <TypeInfo>typeInfo;
+  }
+
+  write(accessor: string): string {
+    const item = this.scope.uniqueName("item");
+    return `
+        ${this.builder.writer.varUInt32(`${accessor}.length * 2`)}
+        ${this.builder.writer.reserve(`${accessor}.length * 2`)};
+        for (const ${item} of ${accessor}) {
+          ${this.builder.writer.float16(item)}
+        }
+    `;
+  }
+
+  read(accessor: (expr: string) => string, refState: string): string {
+    const result = this.scope.uniqueName("result");
+    const len = this.scope.uniqueName("len");
+    const idx = this.scope.uniqueName("idx");
+    return `
+        const ${len} = ${this.builder.reader.varUInt32()} / 2;
+        const ${result} = new Array(${len});
+        ${this.maybeReference(result, refState)}
+        for (let ${idx} = 0; ${idx} < ${len}; ${idx}++) {
+          ${result}[${idx}] = ${this.builder.reader.float16()};
+        }
+        ${accessor(result)}
+      `;
+  }
+
+  getFixedSize(): number {
+    return 7;
+  }
+}
+CodegenRegistry.register(TypeId.BOOL_ARRAY, BoolArraySerializerGenerator);
+CodegenRegistry.register(TypeId.BINARY, build(Type.uint8(), `Uint8Array`, 1));
+CodegenRegistry.register(TypeId.INT8_ARRAY, build(Type.int8(), `Int8Array`, 
1));
+CodegenRegistry.register(TypeId.INT16_ARRAY, build(Type.int16(), `Int16Array`, 
2));
+CodegenRegistry.register(TypeId.INT32_ARRAY, build(Type.int32(), `Int32Array`, 
4));
+CodegenRegistry.register(TypeId.INT64_ARRAY, build(Type.int64(), 
`BigInt64Array`, 8));
+CodegenRegistry.register(TypeId.UINT8_ARRAY, build(Type.uint8(), `Uint8Array`, 
1));
+CodegenRegistry.register(TypeId.UINT16_ARRAY, build(Type.uint16(), 
`Uint16Array`, 2));
+CodegenRegistry.register(TypeId.UINT32_ARRAY, build(Type.uint32(), 
`Uint32Array`, 4));
+CodegenRegistry.register(TypeId.UINT64_ARRAY, build(Type.uint64(), 
`BigUint64Array`, 8));
+CodegenRegistry.register(TypeId.FLOAT16_ARRAY, 
Float16ArraySerializerGenerator);
+CodegenRegistry.register(TypeId.FLOAT32_ARRAY, build(Type.float32(), 
`Float32Array`, 4));
+CodegenRegistry.register(TypeId.FLOAT64_ARRAY, build(Type.float64(), 
`Float64Array`, 6));
diff --git a/javascript/packages/fory/lib/meta/TypeMeta.ts 
b/javascript/packages/fory/lib/meta/TypeMeta.ts
index 6ade956fc..f52114baa 100644
--- a/javascript/packages/fory/lib/meta/TypeMeta.ts
+++ b/javascript/packages/fory/lib/meta/TypeMeta.ts
@@ -131,6 +131,10 @@ class FieldInfo {
     return this.typeId;
   }
 
+  getUserTypeId() {
+    return this.userTypeId;
+  }
+
   hasFieldId() {
     return typeof this.fieldId === "number";
   }
@@ -332,13 +336,14 @@ export class TypeMeta {
     const encodingFlags = (header >>> 6) & 0b11;
     let size = (header >>> 2) & 0b1111;
     const bigSize = size === FIELD_NAME_SIZE_THRESHOLD;
-
+    const nullable = (header & 0b10) > 0;
+    const trackingRef = (header & 0b1) > 0;
     if (bigSize) {
       size += reader.readVarUint32Small7();
     }
 
     // Read type ID
-    const { typeId, userTypeId, trackingRef, nullable, options, fieldId } = 
this.readTypeId(reader);
+    const { typeId, userTypeId, options, fieldId } = this.readTypeId(reader);
 
     let fieldName: string;
     if (encodingFlags === 3) {
@@ -751,7 +756,7 @@ export class TypeMeta {
     listFields.sort(typeIdThenNameSorter);
     setFields.sort(typeIdThenNameSorter);
     mapFields.sort(typeIdThenNameSorter);
-    otherFields.sort(typeIdThenNameSorter);
+    otherFields.sort(nameSorter);
 
     return [
       primitiveFields,
diff --git a/javascript/packages/fory/lib/typeInfo.ts 
b/javascript/packages/fory/lib/typeInfo.ts
index c5c3ac368..9359eb7ae 100644
--- a/javascript/packages/fory/lib/typeInfo.ts
+++ b/javascript/packages/fory/lib/typeInfo.ts
@@ -115,7 +115,7 @@ export class TypeInfo<T = unknown> extends 
ExtensibleFunction {
     TypeInfo.fory = null;
   }
 
-  private constructor(private _typeId: number, userTypeId = -1) {
+  public constructor(private _typeId: number, userTypeId = -1) {
     super(function (target: any, key?: string | { name?: string }) {
       if (key === undefined) {
         initMeta(target, that as unknown as StructTypeInfo);
@@ -582,7 +582,11 @@ export type HintResult<T> = T extends never ? any : T 
extends {
   : T extends {
     type: typeof TypeId.DURATION;
   }
-  ? Date
+  ? number
+  : T extends {
+    type: typeof TypeId.DATE;
+  }
+  ? (Date | number)
   : T extends {
     type: typeof TypeId.TIMESTAMP;
   }
@@ -788,6 +792,11 @@ export const Type = {
       (TypeId.DURATION),
     );
   },
+  date() {
+    return TypeInfo.fromNonParam<typeof TypeId.DATE>(
+      (TypeId.DATE),
+    );
+  },
   timestamp() {
     return TypeInfo.fromNonParam<typeof TypeId.TIMESTAMP>(
       (TypeId.TIMESTAMP),
@@ -825,13 +834,13 @@ export const Type = {
   },
   uint8Array() {
     return TypeInfo.fromNonParam<typeof TypeId.UINT8_ARRAY>(
-      (TypeId.INT8_ARRAY),
+      (TypeId.UINT8_ARRAY),
 
     );
   },
   uint16Array() {
     return TypeInfo.fromNonParam<typeof TypeId.UINT16_ARRAY>(
-      (TypeId.INT16_ARRAY),
+      (TypeId.UINT16_ARRAY),
 
     );
   },
@@ -843,7 +852,7 @@ export const Type = {
   },
   uint64Array() {
     return TypeInfo.fromNonParam<typeof TypeId.UINT64_ARRAY>(
-      (TypeId.INT64_ARRAY),
+      (TypeId.UINT64_ARRAY),
 
     );
   },
diff --git a/javascript/packages/fory/lib/typeMetaResolver.ts 
b/javascript/packages/fory/lib/typeMetaResolver.ts
index 00ede32f4..f7de94461 100644
--- a/javascript/packages/fory/lib/typeMetaResolver.ts
+++ b/javascript/packages/fory/lib/typeMetaResolver.ts
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import { StructTypeInfo, TypeInfo } from "./typeInfo";
+import { StructTypeInfo, Type, TypeInfo } from "./typeInfo";
 import fory from "./fory";
 import { TypeMeta } from "./meta/TypeMeta";
 import { BinaryReader } from "./reader";
@@ -38,9 +38,9 @@ export class TypeMetaResolver {
       const typeId = x.getTypeId();
       const fieldName = x.getFieldName();
       const declared = typeInfo.options.props?.[fieldName];
-      const fieldTypeInfo = declared ?? 
this.fory.typeResolver.getTypeInfo(typeId);
+      let fieldTypeInfo = declared ?? 
this.fory.typeResolver.getTypeInfo(typeId);
       if (!fieldTypeInfo) {
-        throw new Error(`typeid: ${typeId} in prop ${fieldName} not 
registered`);
+        fieldTypeInfo = Type.any();
       }
       if (!typeInfo.options.fieldInfo) {
         typeInfo.options.fieldInfo = {};
@@ -62,12 +62,16 @@ export class TypeMetaResolver {
     let typeInfo;
     if (!TypeId.isNamedType(typeId)) {
       typeInfo = this.fory.typeResolver.getTypeInfo(typeId, userTypeId);
+      if (!typeInfo) {
+        typeInfo = Type.struct({ typeId });
+      }
     } else {
       typeInfo = this.fory.typeResolver.getTypeInfo(`${ns}$${typeName}`);
+      if (!typeInfo) {
+        typeInfo = Type.struct({ typeName, namespace: ns });
+      }
     }
-    if (!typeInfo) {
-      throw new Error(`${typeId} not registered`); // todo
-    }
+
     this.updateTypeInfo(typeMeta, typeInfo);
     return this.fory.replaceSerializerReader(typeInfo);
   }
diff --git a/javascript/packages/fory/lib/typeResolver.ts 
b/javascript/packages/fory/lib/typeResolver.ts
index 9dbab56da..e11de059a 100644
--- a/javascript/packages/fory/lib/typeResolver.ts
+++ b/javascript/packages/fory/lib/typeResolver.ts
@@ -86,6 +86,8 @@ export default class TypeResolver {
       return this.registerSerializer(typeInfo, new 
Gen(this.fory).generateSerializer(typeInfo));
     };
     registerSerializer(Type.string());
+    registerSerializer(new TypeInfo(TypeId.ENUM));
+    registerSerializer(new TypeInfo(TypeId.NAMED_ENUM));
     registerSerializer(Type.any());
     registerSerializer(Type.array(Type.any()));
     registerSerializer(Type.map(Type.any(), Type.any()));
@@ -112,12 +114,17 @@ export default class TypeResolver {
     registerSerializer(Type.float64());
     registerSerializer(Type.timestamp());
     registerSerializer(Type.duration());
+    registerSerializer(Type.date());
     registerSerializer(Type.set(Type.any()));
     registerSerializer(Type.binary());
     registerSerializer(Type.boolArray());
+    registerSerializer(Type.uint8Array());
     registerSerializer(Type.int8Array());
+    registerSerializer(Type.uint16Array());
     registerSerializer(Type.int16Array());
+    registerSerializer(Type.uint32Array());
     registerSerializer(Type.int32Array());
+    registerSerializer(Type.uint64Array());
     registerSerializer(Type.int64Array());
     registerSerializer(Type.float16Array());
     registerSerializer(Type.float32Array());
@@ -126,10 +133,10 @@ export default class TypeResolver {
     this.float64Serializer = this.getSerializerById(TypeId.FLOAT64);
     this.float32Serializer = this.getSerializerById(TypeId.FLOAT32);
     this.varint32Serializer = this.getSerializerById(TypeId.VARINT32);
-    this.taggedint64Serializer = this.getSerializerById(TypeId.TAGGED_INT64);
+    this.varInt64Serializer = this.getSerializerById(TypeId.VARINT64);
     this.int64Serializer = this.getSerializerById((TypeId.INT64));
     this.boolSerializer = this.getSerializerById((TypeId.BOOL));
-    this.dateSerializer = this.getSerializerById((TypeId.TIMESTAMP));
+    this.datetimeSerializer = this.getSerializerById((TypeId.TIMESTAMP));
     this.stringSerializer = this.getSerializerById((TypeId.STRING));
     this.setSerializer = this.getSerializerById((TypeId.SET));
     this.arraySerializer = this.getSerializerById((TypeId.LIST));
@@ -142,15 +149,17 @@ export default class TypeResolver {
     this.int16ArraySerializer = this.getSerializerById(TypeId.INT16_ARRAY);
     this.int32ArraySerializer = this.getSerializerById(TypeId.INT32_ARRAY);
     this.int64ArraySerializer = this.getSerializerById(TypeId.INT64_ARRAY);
+    this.float32ArraySerializer = this.getSerializerById(TypeId.FLOAT32_ARRAY);
+    this.float64ArraySerializer = this.getSerializerById(TypeId.FLOAT64_ARRAY);
   }
 
   private float64Serializer: null | Serializer = null;
   private float32Serializer: null | Serializer = null;
   private varint32Serializer: null | Serializer = null;
-  private taggedint64Serializer: null | Serializer = null;
+  private varInt64Serializer: null | Serializer = null;
   private int64Serializer: null | Serializer = null;
   private boolSerializer: null | Serializer = null;
-  private dateSerializer: null | Serializer = null;
+  private datetimeSerializer: null | Serializer = null;
   private stringSerializer: null | Serializer = null;
   private setSerializer: null | Serializer = null;
   private arraySerializer: null | Serializer = null;
@@ -163,6 +172,8 @@ export default class TypeResolver {
   private int16ArraySerializer: null | Serializer = null;
   private int32ArraySerializer: null | Serializer = null;
   private int64ArraySerializer: null | Serializer = null;
+  private float32ArraySerializer: null | Serializer = null;
+  private float64ArraySerializer: null | Serializer = null;
 
   constructor(private fory: Fory) {
   }
@@ -265,7 +276,7 @@ export default class TypeResolver {
     if (typeof v === "number") {
       if (Number.isInteger(v)) {
         if (v > MaxInt32 || v < MinInt32) {
-          return this.taggedint64Serializer;
+          return this.varInt64Serializer;
         }
         return this.varint32Serializer;
       }
@@ -276,7 +287,7 @@ export default class TypeResolver {
     }
 
     if (typeof v === "bigint") {
-      return this.taggedint64Serializer;
+      return this.varInt64Serializer;
     }
 
     if (typeof v === "string") {
@@ -315,6 +326,14 @@ export default class TypeResolver {
       return this.int64ArraySerializer;
     }
 
+    if (v instanceof Float32Array) {
+      return this.float32ArraySerializer;
+    }
+
+    if (v instanceof Float64Array) {
+      return this.float64ArraySerializer;
+    }
+
     if (Array.isArray(v)) {
       return this.arraySerializer;
     }
@@ -328,7 +347,7 @@ export default class TypeResolver {
     }
 
     if (v instanceof Date) {
-      return this.dateSerializer;
+      return this.datetimeSerializer;
     }
 
     if (v instanceof Map) {
diff --git a/javascript/packages/fory/lib/writer/index.ts 
b/javascript/packages/fory/lib/writer/index.ts
index 5c4036602..bbb28a419 100644
--- a/javascript/packages/fory/lib/writer/index.ts
+++ b/javascript/packages/fory/lib/writer/index.ts
@@ -218,6 +218,12 @@ export class BinaryWriter {
     this.cursor += 8;
   }
 
+  arrayBuffer(v: ArrayBuffer, byteOffset: number, byteLength: number) {
+    this.reserve(byteLength);
+    this.platformBuffer.set(new Uint8Array(v, byteOffset, byteLength), 
this.cursor);
+    this.cursor += byteLength;
+  }
+
   buffer(v: ArrayLike<number>) {
     this.reserve(v.length);
     this.platformBuffer.set(v, this.cursor);
diff --git a/javascript/test/array.test.ts b/javascript/test/array.test.ts
index 2a53633f0..c8c094858 100644
--- a/javascript/test/array.test.ts
+++ b/javascript/test/array.test.ts
@@ -54,24 +54,24 @@ describe('array', () => {
       a6: Type.float64Array()
     });
 
-    const fory = new Fory({ refTracking: true }); const serializer = 
fory.registerSerializer(typeinfo).serializer;
+    const fory = new Fory({ refTracking: true }); 
+    const serializer = fory.registerSerializer(typeinfo).serializer;
     const input = fory.serialize({
       a: [true, false],
-      a2: [1, 2, 3],
-      a3: [3, 5, 76],
-      a4: [634, 564, 76],
-      a6: [234243.555, 55654.6786],
+      a2: new Int16Array([1, 2, 3]),
+      a3: new Int32Array([3, 5, 76]),
+      a4: new BigInt64Array([634n, 564n, 76n]),
+      a6: new Float64Array([234243.555, 55654.679]),
     }, serializer);
     const result = fory.deserialize(
       input
     );
-    result.a4 = result.a4.map(x => Number(x));
     expect(result).toEqual({
       a: [true, false],
-      a2: [1, 2, 3],
-      a3: [3, 5, 76],
-      a4: [634, 564, 76],
-      a6: [234243.555, 55654.6786],
+      a2: new Int16Array([1, 2, 3]),
+      a3: new Int32Array([3, 5, 76]),
+      a4: new BigInt64Array([634n, 564n, 76n]),
+      a6: new Float64Array([234243.555, 55654.679]),
     })
   });
 
@@ -85,7 +85,7 @@ describe('array', () => {
 
     const fory = new Fory({ refTracking: true }); const serialize = 
fory.registerSerializer(typeinfo).serializer;
     const input = fory.serialize({
-      a5: [2.43, 654.4, 55],
+      a5: new Float32Array([2.43, 654.4, 55]),
     }, serialize);
     const result = fory.deserialize(
       input
diff --git a/javascript/test/crossLanguage.test.ts 
b/javascript/test/crossLanguage.test.ts
index a21925f71..af5129efb 100644
--- a/javascript/test/crossLanguage.test.ts
+++ b/javascript/test/crossLanguage.test.ts
@@ -27,6 +27,7 @@ import Fory, {
 import { describe, expect, test } from "@jest/globals";
 import * as fs from "node:fs";
 import * as beautify from 'js-beautify';
+import { TypeId } from "../packages/fory/lib/type";
 
 const Byte = {
   MAX_VALUE: 127,
@@ -223,11 +224,11 @@ describe("bool", () => {
       Blue: 2,
       White: 3,
     };
-    fory.registerSerializer(Type.enum(101, Color));
+    const { serialize: colorSerialize } = 
fory.registerSerializer(Type.enum(101, Color));
     // Deserialize various data types from Java
     const deserializedData = [];
     let cursor = 0;
-    for (let i = 0; i < 28; i++) { // 28 serialized items from Java
+    for (let i = 0; i < 27; i++) { // 28 serialized items from Java
       const deserializedItem = fory.deserialize(content.subarray(cursor));
       cursor += fory.binaryReader.getCursor();
       deserializedData.push(deserializedItem);
@@ -236,8 +237,26 @@ describe("bool", () => {
 
     const bfs = []
     // Serialize each deserialized item back
-    for (const item of deserializedData) {
-      const serializedData = fory.serialize(item);
+    for (let index = 0; index < deserializedData.length; index++) {
+      const item = deserializedData[index];
+      let serializedData;
+      if (index === 11) {
+        serializedData = fory.serialize(item, 
fory.typeResolver.getSerializerById(TypeId.FLOAT32));
+      } else if (index === 12) {
+        serializedData = fory.serialize(item, 
fory.typeResolver.getSerializerById(TypeId.FLOAT64));
+      } else if (index === 14) {
+        serializedData = fory.serialize(item, 
fory.typeResolver.getSerializerById(TypeId.DATE));
+      } else if (index === 15) {
+        serializedData = fory.serialize(item, 
fory.typeResolver.getSerializerById(TypeId.TIMESTAMP));
+      } else if (index === 16) {
+        serializedData = fory.serialize(item, 
fory.typeResolver.getSerializerById(TypeId.BOOL_ARRAY));
+      } else if (index === 17) {
+        serializedData = fory.serialize(item, 
fory.typeResolver.getSerializerById(TypeId.BINARY));
+      } else if (index === 26) {
+        serializedData = colorSerialize(item);
+      } else {
+        serializedData = fory.serialize(item);
+      }
       bfs.push(serializedData);
     }
 
@@ -621,50 +640,172 @@ describe("bool", () => {
   });
 
   test("test_skip_id_custom", () => {
-    if (Boolean("1")) { return; }
-    const fory = new Fory({
+    const fory1 = new Fory({
       compatible: true
     });
 
+    @Type.ext(103)
+    class MyExt {
+      id: number = 0;
+    }
+    fory1.registerSerializer(MyExt, {
+      write: (value: MyExt, writer: BinaryWriter, fory: Fory) => {
+        writer.varInt32(value.id);
+      },
+      read: (result: MyExt, reader: BinaryReader, fory: Fory) => {
+        result.id = reader.varInt32();
+      }
+    });
+
     // Define empty wrapper for deserialization
     @Type.struct(104)
-    class EmptyWrapper { }
-    fory.registerSerializer(EmptyWrapper);
+    class Empty { }
+    fory1.registerSerializer(Empty);
 
-    const reader = new BinaryReader({});
-    reader.reset(content);
+    const fory2 = new Fory({
+      compatible: true
+    });
 
-    // Deserialize empty wrapper from Java
-    let cursor = 0;
-    const deserializedWrapper = fory.deserialize(content.subarray(cursor));
-    cursor += fory.binaryReader.getCursor();
+    // Define Color enum
+    const Color = {
+      Green: 0,
+      Red: 1,
+      Blue: 2,
+      White: 3,
+    };
+    fory2.registerSerializer(Type.enum(101, Color));
 
-    // Serialize the deserialized wrapper back
-    const serializedData = fory.serialize(deserializedWrapper);
+    @Type.struct(102, {
+      id: Type.varInt32()
+    })
+    class MyStruct {
+      id: number = 0;
+    }
+    fory2.registerSerializer(MyStruct);
+
+    fory2.registerSerializer(MyExt, {
+      write: (value: MyExt, writer: BinaryWriter, fory: Fory) => {
+        writer.varInt32(value.id);
+      },
+      read: (result: MyExt, reader: BinaryReader, fory: Fory) => {
+        result.id = reader.varInt32();
+      }
+    });
+
+    @Type.struct(104, {
+      color: Type.enum(101, Color),
+      myStruct: Type.struct(102),
+      myExt: Type.ext(103)
+    })
+    class MyWrapper {
+      color: number = 0;
+      myStruct: MyStruct = new MyStruct();
+      myExt: MyExt = new MyExt();
+    }
+    fory2.registerSerializer(MyWrapper);
+
+
+    // Deserialize empty from Java
+    let cursor = 0;
+    const deserializedEmpty = fory1.deserialize(content.subarray(cursor));
+    cursor += fory1.binaryReader.getCursor();
+    expect(deserializedEmpty instanceof Empty).toEqual(true);
+
+    // Create wrapper object
+    const wrapper = new MyWrapper();
+    wrapper.color = Color.White;
+    wrapper.myStruct = new MyStruct();
+    wrapper.myStruct.id = 42;
+    wrapper.myExt = new MyExt();
+    wrapper.myExt.id = 43;
+
+    // Serialize wrapper
+    const serializedData = fory2.serialize(wrapper);
     writeToFile(serializedData as Buffer);
   });
 
   test("test_skip_name_custom", () => {
-    if (Boolean("1")) { return; }
-    const fory = new Fory({
+    const fory1 = new Fory({
       compatible: true
     });
 
+    @Type.ext("my_ext")
+    class MyExt {
+      id: number = 0;
+    }
+    fory1.registerSerializer(MyExt, {
+      write: (value: MyExt, writer: BinaryWriter, fory: Fory) => {
+        writer.varInt32(value.id);
+      },
+      read: (result: MyExt, reader: BinaryReader, fory: Fory) => {
+        result.id = reader.varInt32();
+      }
+    });
+
     // Define empty wrapper for deserialization
-    @Type.struct({ namespace: "", typeName: "my_wrapper" })
-    class EmptyWrapper { }
-    fory.registerSerializer(EmptyWrapper);
+    @Type.struct("my_wrapper")
+    class Empty { }
+    fory1.registerSerializer(Empty);
 
-    const reader = new BinaryReader({});
-    reader.reset(content);
+    const fory2 = new Fory({
+      compatible: true
+    });
 
-    // Deserialize empty wrapper from Java
-    let cursor = 0;
-    const deserializedWrapper = fory.deserialize(content.subarray(cursor));
-    cursor += fory.binaryReader.getCursor();
+    // Define Color enum
+    const Color = {
+      Green: 0,
+      Red: 1,
+      Blue: 2,
+      White: 3,
+    };
+    fory2.registerSerializer(Type.enum("color", Color));
 
-    // Serialize the deserialized wrapper back
-    const serializedData = fory.serialize(deserializedWrapper);
+    @Type.struct("my_struct", {
+      id: Type.varInt32()
+    })
+    class MyStruct {
+      id: number = 0;
+    }
+    fory2.registerSerializer(MyStruct);
+
+    fory2.registerSerializer(MyExt, {
+      write: (value: MyExt, writer: BinaryWriter, fory: Fory) => {
+        writer.varInt32(value.id);
+      },
+      read: (result: MyExt, reader: BinaryReader, fory: Fory) => {
+        result.id = reader.varInt32();
+      }
+    });
+
+    @Type.struct("my_wrapper", {
+      color: Type.enum("color", Color),
+      myStruct: Type.struct("my_struct"),
+      myExt: Type.ext("my_ext")
+    })
+    class MyWrapper {
+      color: number = 0;
+      myStruct: MyStruct = new MyStruct();
+      myExt: MyExt = new MyExt();
+    }
+    fory2.registerSerializer(MyWrapper);
+
+
+    // Deserialize empty from Java
+    let cursor = 0;
+    const deserializedEmpty = fory1.deserialize(content.subarray(cursor));
+    cursor += fory1.binaryReader.getCursor();
+    expect(deserializedEmpty instanceof Empty).toEqual(true);
+
+    // Create wrapper object
+    const wrapper = new MyWrapper();
+    wrapper.color = Color.White;
+    wrapper.myStruct = new MyStruct();
+    wrapper.myStruct.id = 42;
+    wrapper.myExt = new MyExt();
+    wrapper.myExt.id = 43;
+
+    // Serialize wrapper
+    const serializedData = fory2.serialize(wrapper);
     writeToFile(serializedData as Buffer);
   });
 
@@ -832,7 +973,7 @@ describe("bool", () => {
     })
     class Dog {
       age: number = 0;
-      @ForyField({ nullable: true})
+      @ForyField({ nullable: true })
       name: string | null = null;
     }
     fory.registerSerializer(Dog);
@@ -953,8 +1094,31 @@ describe("bool", () => {
     writeToFile(serializedData as Buffer);
   });
 
+  test("test_schema_evolution_compatible_reverse", () => {
+    const fory = new Fory({
+      compatible: true
+    });
+
+    @Type.struct(200)
+    class TwoStringFieldStruct {
+      @Type.string()
+      f1: string = "";
+      @Type.string()
+      f2: string = "";
+    }
+    fory.registerSerializer(TwoStringFieldStruct);
+
+    // Deserialize empty struct from Java
+    let cursor = 0;
+    const deserializedStruct = fory.deserialize(content.subarray(cursor));
+    cursor += fory.binaryReader.getCursor();
+
+    // Serialize the deserialized struct back
+    const serializedData = fory.serialize(deserializedStruct);
+    writeToFile(serializedData as Buffer);
+  });
+
   test("test_schema_evolution_compatible", () => {
-    if (Boolean("1")) { return; }
     const fory = new Fory({
       compatible: true
     });
@@ -963,9 +1127,6 @@ describe("bool", () => {
     class EmptyStruct { }
     fory.registerSerializer(EmptyStruct);
 
-    const reader = new BinaryReader({});
-    reader.reset(content);
-
     // Deserialize empty struct from Java
     let cursor = 0;
     const deserializedStruct = fory.deserialize(content.subarray(cursor));
@@ -1073,8 +1234,41 @@ describe("bool", () => {
     writeToFile(serializedData as Buffer);
   });
 
+  test("test_enum_schema_evolution_compatible_reverse", () => {
+    const fory = new Fory({
+      compatible: true
+    });
+
+    // Define and register TestEnum
+    const TestEnum = {
+      VALUE_A: 0,
+      VALUE_B: 1,
+      VALUE_C: 2,
+    };
+    fory.registerSerializer(Type.enum(210, TestEnum));
+
+    @Type.struct(211, {
+      f1: Type.enum(210, TestEnum),
+      f2: Type.enum(210, TestEnum)
+    })
+    class TwoEnumFieldStruct {
+      f1: number = 0; // enum value
+      f2: number = 0; // enum value
+    }
+    fory.registerSerializer(TwoEnumFieldStruct);
+
+    // Deserialize struct from Java
+    let cursor = 0;
+    const deserializedStruct = fory.deserialize(content.subarray(cursor));
+    cursor += fory.binaryReader.getCursor();
+
+    // Serialize the deserialized struct back
+    const serializedData = fory.serialize(deserializedStruct);
+    writeToFile(serializedData as Buffer);
+  });
+
+
   test("test_enum_schema_evolution_compatible", () => {
-    if (Boolean("1")) { return; }
     const fory = new Fory({
       compatible: true
     });
@@ -1091,9 +1285,6 @@ describe("bool", () => {
     class EmptyStruct { }
     fory.registerSerializer(EmptyStruct);
 
-    const reader = new BinaryReader({});
-    reader.reset(content);
-
     // Deserialize empty struct from Java
     let cursor = 0;
     const deserializedStruct = fory.deserialize(content.subarray(cursor));
diff --git a/javascript/test/datetime.test.ts b/javascript/test/datetime.test.ts
index b0b169230..73c77346e 100644
--- a/javascript/test/datetime.test.ts
+++ b/javascript/test/datetime.test.ts
@@ -26,10 +26,11 @@ describe('datetime', () => {
     const fory = new Fory({ refTracking: true });    
     const now = new Date();
     const input = fory.serialize(now);
-    const result = fory.deserialize(
+    const result: Date | null = fory.deserialize(
         input
     );
-    expect(result).toEqual(now)
+    expect(result?.getFullYear()).toEqual(now.getFullYear())
+    expect(result?.getDate()).toEqual(now.getDate())
   });
   test('should datetime work', () => {
     const typeinfo = Type.struct("example.foo", {
@@ -43,7 +44,7 @@ describe('datetime', () => {
     const result = fory.deserialize(
       input
     );
-    expect(result).toEqual({ a: d, b: new Date('2021/10/20 00:00') })
+    expect(result).toEqual({ a: d, b: d.getTime() })
   });
 });
 
diff --git a/javascript/test/fory.test.ts b/javascript/test/fory.test.ts
index a84758717..2f5c4d7ad 100644
--- a/javascript/test/fory.test.ts
+++ b/javascript/test/fory.test.ts
@@ -73,7 +73,7 @@ describe('fory', () => {
         testTypeInfo(typeinfo6, 123.456789)
 
         const typeinfo7 = Type.binary()
-        testTypeInfo(typeinfo7, new Uint8Array([1, 2, 3]), fromUint8Array(new 
Uint8Array([1, 2, 3])));
+        testTypeInfo(typeinfo7, new Uint8Array([1, 2, 3]), new Uint8Array([1, 
2, 3]));
 
         const typeinfo8 = Type.string()
         testTypeInfo(typeinfo8, '123')
diff --git a/javascript/test/object.test.ts b/javascript/test/object.test.ts
index 257da2ed1..7270270b0 100644
--- a/javascript/test/object.test.ts
+++ b/javascript/test/object.test.ts
@@ -113,7 +113,7 @@ describe('object', () => {
       input
     );
     result.a.forEach(x => x.e = Number(x.e))
-    expect(result).toEqual({ a: [{ b: "hel", c: true, d: 123, e: 123, f: 
Buffer.from([1, 2, 3]) }] })
+    expect(result).toEqual({ a: [{ b: "hel", c: true, d: 123, e: 123, f: new 
Uint8Array([1, 2, 3]) }] })
   });
 
   test('should write tag and read tag work', () => {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to