-
Notifications
You must be signed in to change notification settings - Fork 0
Typed Document
Typed Document (TDoc)
适用版本:4.0.0。
Applies to 4.0.0.
首页 · 脚本 TDoc API · .NET TDoc API
Introduction
TDoc 是 AuroraScript 的带类型文本数据格式。它将一个 AuroraScript 值写成独立文档,并在读取时恢复普通对象、数组、Packed Array、Date、Path、Regex、HashMap、StringBuffer 与宿主已注册的 CLR/CIL 对象。
TDoc is AuroraScript's typed text-data format. It writes one AuroraScript value as a standalone document and restores ordinary objects, arrays, packed arrays,
Date,Path,Regex,HashMap,StringBuffer, and host-registered CLR/CIL objects when read.
TDoc 不是第二套脚本语法:文档内容不会执行代码,也不支持变量、函数调用、脚本 tdoc 标记或内联表达式。独立文档从根值直接开始。
TDoc is not a second scripting syntax: document content does not execute code and does not support variables, calls, the script
tdocmarker, or inline expressions. A standalone document starts directly with its root value.
Use Cases
- 保存需要保留 AuroraScript 类型身份的配置、快照或持久化状态。
Persist configuration, snapshots, or state that must retain AuroraScript type identity.
- 在同一 AuroraScript 宿主之间交换数据,并且需要保留 Packed Array 或
Date等类型。Exchange data between AuroraScript hosts when types such as packed arrays or
Datemust be preserved. - 将经
AuroraEngine.RegisterType明确注册的 CLR/CIL 对象写入受控数据契约。Write CLR/CIL objects explicitly registered through
AuroraEngine.RegisterTypeinto a controlled data contract.
TDoc 不会将运行时行为当成持久化数据。写入时,函数、代理、访问器属性、未注册 CLR/CIL 对象、非有限 Number,以及已在当前文档中出现过的循环/共享引用都会按“可跳过值”处理,而不是使整个 stringify 失败。
TDoc does not treat runtime behavior as persistent data. When writing, functions, proxies, accessor properties, unregistered CLR/CIL objects, non-finite Numbers, and circular/shared references already seen in the current document are treated as skippable values rather than failing the entire
stringify.
Quick Example
Object {
readonly String id "u-001",
String name "Aurora",
Number version 4,
Int8Array payload [-128, 0, 127],
Date createdAt "2026-08-20 10:00:00",
}
上面的文档根值是 ScriptObject;id 是浅只读属性,payload 保持为 ScriptInt8Array,而不是一般 Array。
The root value above is a
ScriptObject;idis a shallow read-only property andpayloadremains aScriptInt8Array, rather than becoming a generalArray.
脚本中使用 TDoc:
Use
TDocin scripts:
var profile = TDoc.parse('Object { String name "Aurora", Int8Array levels [1, 2] }');
var text = TDoc.stringify(profile, false);
return text;宿主中使用 AuroraTypedDocument:
Use
AuroraTypedDocumentin a host:
var tdoc = new AuroraTypedDocument(engine);
var text = tdoc.Serialize(ScriptDatum.FromString("Aurora"));
var value = tdoc.Deserialize(text);Object View and Skippable Values
普通 ScriptObject 会按脚本可见的可枚举属性写入:先取自身属性,再沿 prototype 链取未被遮蔽的属性。写入后的 TDoc 是一个扁平对象;prototype 身份、原型链和访问器本身不会保留。
An ordinary
ScriptObjectis written from its script-visible enumerable properties: own properties first, then unshadowed properties along its prototype chain. The resulting TDoc is a flat object; prototype identity, the prototype chain, and accessors themselves are not preserved.
stringify 遇到不可表示的运行时值时采用固定的无异常降级规则:对象属性(包括从 prototype 看到的属性)会被省略;数组元素会写为 null 以保持索引;HashMap 条目中的不可表示键或值会写为 null;根值不可表示时结果为 null。因此 TDoc 是数据快照,不是完整对象图的保真克隆。
stringifyuses fixed, non-throwing degradation for unrepresentable runtime values: object properties (including properties visible through a prototype) are omitted; array elements becomenullto preserve indices; an unrepresentable key or value in aHashMapentry becomesnull; and an unrepresentable root becomesnull. TDoc is therefore a data snapshot, not a lossless clone of a full object graph.
var action = () => true;
var value = { name: "Aurora", cancel: action, values: [1, action, 3] };
TDoc.stringify(value, false);
// {name "Aurora",values [1,null,3,],}Text Structure
一个文档只允许一个根值。类型名可显式写出;未写出时,只有原始字面量可唯一确定的类型会自动推断。
A document permits one root value. A type name may be explicit; when it is absent, only values uniquely determined by their raw literal are inferred automatically.
document = typed-value EOF ;
typed-value = [ type-name ] raw-value ;
raw-value = "null" | boolean | number | string | array | object ;
array = "[" [ typed-value { "," typed-value } [ "," ] ] "]" ;
object = "{" [ member { "," member } [ "," ] ] "}" ;
member = [ "readonly" ] [ type-name ] property-name raw-value ;
property-name = identifier | string ;
type-name = identifier ;对象成员中,两个连续标识符表示“类型名 + 属性名”;只有一个标识符时,它是属性名。例如 String name "Aurora" 显式声明 String,而 name "Aurora" 让读取器推断字符串。
In an object member, two consecutive identifiers mean “type name + property name”; one identifier is the property name. For example,
String name "Aurora"explicitly declaresString, whilename "Aurora"lets the reader infer a string.
字符串值必须使用单引号或双引号。Object { id UX01 } 和 Object { id UX01-03 } 都无效:前者中的 UX01 是标识符位置,后者的 - 也不属于标识符。请写为 Object { id "UX01" } 或 Object { id "UX01-03" }。
String values must use single or double quotes.
Object { id UX01 }andObject { id UX01-03 }are both invalid:UX01is in an identifier position in the former, and-is not part of an identifier in the latter. WriteObject { id "UX01" }orObject { id "UX01-03" }instead.
支持 // 行注释、/* ... */ 块注释和尾逗号。脚本 tdoc 标记在独立文档中无效并会产生语法错误。
Line comments (
//), block comments (/* ... */), and trailing commas are supported. The scripttdocmarker is invalid in standalone documents and produces a syntax error.
Types and Inference
| 文本形状 | 读取结果 | 默认是否输出类型名 |
|---|---|---|
null |
Null |
否 |
true / false
|
Boolean |
否 |
42 / 1.5 / 0xFF
|
Number(double) |
否 |
"text" / 'text'
|
String |
否 |
[ ... ] |
ScriptArray |
否 |
{ ... } |
ScriptObject |
否 |
StringBuffer "text" |
StringBuffer |
是 |
Date "..." / Date 14425655658
|
ScriptDate |
是 |
Regex { ... } |
ScriptRegex |
是 |
Path "a/b.as" |
ScriptPathValue |
是 |
HashMap [[key, value]] |
ScriptHashMap |
是 |
Int32Array / Int8Array / Float64Array / BooleanArray
|
对应 Packed Array | 始终是 |
已注册类型,例如 User { ... }
|
已注册 CLR/CIL 实例 | 始终是 |
The table lists read results and whether a type name is emitted by default.
默认 EmitTypeNames 为 false,写入器仅输出无法由原始字面量唯一推断的类型名。Object、Array、String、Number 与 Boolean 默认省略;Date、所有对象形内置类型、所有 Packed Array 和注册 CLR/CIL 类型仍强制输出类型名。将 EmitTypeNames 设为 true 可强制输出所有可用类型名。
EmitTypeNamesdefaults tofalse, so the writer emits only type names that cannot be uniquely inferred from raw literals.Object,Array,String,Number, andBooleanare omitted by default;Date, all object-like built-ins, all packed arrays, and registered CLR/CIL types still force a type name. SetEmitTypeNamestotrueto force every available type name.
// default: EmitTypeNames = false
{ name "Aurora", Int8Array bytes [1, 2] }
// EmitTypeNames = true
Object { String name "Aurora", Int8Array bytes [1, 2] }
readonlyProperties
readonly 是对象属性描述符,不是类型。它使该属性不能再次写入,但不会冻结其对象值。
readonlyis an object-property descriptor, not a type. It prevents the property from being written again, but does not freeze its object value.
Object {
readonly Object settings { retries 3 },
}
读取后 settings = other 会失败,而 settings.retries = 4 仍然可以执行。TDoc 写入器会保留 readonly 标记。
After reading,
settings = otherfails, whilesettings.retries = 4remains valid. The TDoc writer preserves thereadonlymarker.
Date, Regex, and HashMap
Date 的字符串形式必须匹配当前 AuroraEngine 的 EngineOptions.Runtime.DateTimeFormat;数值形式是 .NET ticks,必须是有效整数范围。写入时始终按引擎日期格式输出字符串。
A
Datestring must match the currentAuroraEngineEngineOptions.Runtime.DateTimeFormat; a numeric form is .NET ticks and must be an in-range integer. Writing always produces a string using the engine date format.
Date "2026-08-20 10:00:00"
Regex { pattern "ab+", flags "gi" }
HashMap [["name", "Aurora"], [1, true]]
HashMap 使用二元数组保存键和值,因此非字符串键不会降级为对象属性。
HashMapuses two-element arrays for keys and values, so non-string keys do not degrade into object properties.
CLR/CIL Type Boundary
文档中的 CLR/CIL 类型名必须是当前引擎已经注册的别名。TDoc 不会根据程序集名、.NET 类型名或反射自动加载类型。
A CLR/CIL type name in a document must be an alias already registered on the current engine. TDoc never auto-loads a type from an assembly name, .NET type name, or reflection.
engine.RegisterType<User>("User");
var tdoc = new AuroraTypedDocument(engine);
var user = tdoc.Deserialize("User { String Name \"Hanks\", Number Age 18 }");读取时,未注册对象的显式别名、未知别名、不可构造类型和不符合注册成员契约的文本都会失败;写入时,未注册或不可写入的 CLR/CIL 值按可跳过值规则处理。即使 EmitTypeNames 为 false,User 这类已注册类型名也不会被省略。
When reading, an explicit alias for an unregistered object, an unknown alias, a non-constructible type, or text that violates the registered member contract fails. When writing, an unregistered or non-writable CLR/CIL value follows the skippable-value rules. A registered type name such as
Useris never omitted, even whenEmitTypeNamesisfalse.
Errors and Diagnostics
宿主 API 会抛出 TypedDocumentException。其中 SourceName、Line、Column 和 DataPath 用于定位错误;例如 $.meta.tags[2] 表示嵌套数组中的第三项。
Host APIs throw
TypedDocumentException. ItsSourceName,Line,Column, andDataPathlocate the error; for example,$.meta.tags[2]identifies the third item in a nested array.
脚本 API 将该异常转换为 AuroraRuntimeException,消息以 TDoc.parse error: 或 TDoc.stringify error: 开头。
The script API converts this exception to
AuroraRuntimeException, with a message starting withTDoc.parse error:orTDoc.stringify error:.
Related APIs
AuroraScript.JIT 4.0.0 · Documentation Home · Repository · MIT License