adofai 2.9.7 → 2.9.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adofai",
3
- "version": "2.9.7",
3
+ "version": "2.9.9",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "build": "webpack",
@@ -0,0 +1,128 @@
1
+ const BOM = new Uint8Array([0xef, 0xbb, 0xbf]);
2
+ const COMMA = new Uint8Array([44]); // ASCII for ','
3
+
4
+ export function stripBOM(buffer: ArrayBuffer): ArrayBuffer {
5
+ const view = new Uint8Array(buffer);
6
+ if (view.length >= 3 && view[0] === BOM[0] && view[1] === BOM[1] && view[2] === BOM[2]) {
7
+ return buffer.slice(3);
8
+ }
9
+ return buffer;
10
+ }
11
+
12
+ export function normalizeJsonArrayBuffer(buffer: ArrayBuffer): ArrayBuffer {
13
+ const view = new Uint8Array(buffer);
14
+ let builder: Uint8Array[] = [];
15
+ let last: "other" | "string" | "escape" | "comma" = "other";
16
+ let from = 0;
17
+
18
+ for (let i = 0; i < view.length; i++) {
19
+ const charCode = view[i];
20
+ if (last == "escape") {
21
+ last = "string";
22
+ } else {
23
+ switch (charCode) {
24
+ case 34: // "
25
+ switch (last) {
26
+ case "string":
27
+ last = "other";
28
+ break;
29
+ case "comma":
30
+ builder.push(COMMA);
31
+ default:
32
+ last = "string";
33
+ break;
34
+ }
35
+ break;
36
+ case 92: // \
37
+ if (last === "string") last = "escape";
38
+ break;
39
+ case 44: // ,
40
+ builder.push(view.subarray(from, i));
41
+ from = i + 1;
42
+ if (last === "other") last = "comma";
43
+ break;
44
+ case 93: // ]
45
+ case 125: // }
46
+ if (last === "comma") last = "other";
47
+ break;
48
+ case 9: // \t
49
+ case 10: // \n
50
+ case 11: // \v
51
+ case 12: // \f
52
+ case 13: // \r
53
+ case 32: // space
54
+ break;
55
+ default:
56
+ if (last === "comma") {
57
+ builder.push(COMMA);
58
+ last = "other";
59
+ }
60
+ break;
61
+ }
62
+ }
63
+ }
64
+ builder.push(view.subarray(from));
65
+
66
+ let totalLength = 0;
67
+ for (const arr of builder) {
68
+ totalLength += arr.length;
69
+ }
70
+ const result = new Uint8Array(totalLength);
71
+ let offset = 0;
72
+ for (const arr of builder) {
73
+ result.set(arr, offset);
74
+ offset += arr.length;
75
+ }
76
+ return result.buffer;
77
+ }
78
+
79
+ export function normalizeJsonString(text: string): string {
80
+ const encoder = new TextEncoder();
81
+ const encoded = encoder.encode(text);
82
+ const normalizedBuffer = normalizeJsonArrayBuffer(encoded.buffer);
83
+ const decoder = new TextDecoder('utf-8');
84
+ return decoder.decode(normalizedBuffer);
85
+ }
86
+
87
+ export function decodeStringFromUTF8BOM(buffer: ArrayBuffer): string {
88
+ const strippedBuffer = stripBOM(buffer);
89
+ const decoder = new TextDecoder('utf-8');
90
+ return decoder.decode(strippedBuffer);
91
+ }
92
+
93
+ export function encodeStringAsUTF8BOM(text: string): ArrayBuffer {
94
+ const encoder = new TextEncoder();
95
+ const encoded = encoder.encode(text);
96
+ const bomAndText = new Uint8Array(BOM.length + encoded.length);
97
+ bomAndText.set(BOM, 0);
98
+ bomAndText.set(encoded, BOM.length);
99
+ return bomAndText.buffer;
100
+ }
101
+
102
+ export function decodeJsonFromString(text: string): any {
103
+ return JSON.parse(normalizeJsonString(text));
104
+ }
105
+
106
+ export function decodeJsonFromArrayBuffer(buffer: ArrayBuffer): any {
107
+ return JSON.parse(
108
+ decodeStringFromUTF8BOM(normalizeJsonArrayBuffer(stripBOM(buffer))),
109
+ );
110
+ }
111
+
112
+ export function encodeJsonAsString(obj: any): string {
113
+ return JSON.stringify(obj);
114
+ }
115
+
116
+ export function encodeJsonAsArrayBufferUTF8BOM(obj: any): ArrayBuffer {
117
+ return encodeStringAsUTF8BOM(encodeJsonAsString(obj));
118
+ }
119
+
120
+ export function parse(text: string): any {
121
+ return decodeJsonFromString(text);
122
+ }
123
+
124
+ export function stringify(obj: any): string {
125
+ return encodeJsonAsString(obj);
126
+ }
127
+
128
+ export default { parse, stringify };
@@ -1,5 +1,17 @@
1
- const BOM = Buffer.of(0xef, 0xbb, 0xbf)
2
- const COMMA = Buffer.from(",")
1
+
2
+ let BOM: Buffer;
3
+ let COMMA: Buffer;
4
+
5
+ try {
6
+ BOM = Buffer.of(0xef, 0xbb, 0xbf);
7
+ COMMA = Buffer.from(",");
8
+ } catch (e) {
9
+ console.warn('Buffer is not available in current environment, try to use ArrayBufferParser');
10
+
11
+ // Provide dummy implementations to avoid errors during module loading
12
+ BOM = { equals: () => false, subarray: () => null } as any;
13
+ COMMA = { equals: () => false, subarray: () => null } as any;
14
+ }
3
15
 
4
16
  export function stripBOM(buffer: Buffer): Buffer {
5
17
  if (buffer.length >= 3 && BOM.equals(buffer.subarray(0, 3))) {
@@ -0,0 +1,26 @@
1
+ import StringParser from './StringParser';
2
+
3
+ class Parser {
4
+ static parseError(f: string) {
5
+ return f;
6
+ }
7
+
8
+ /**
9
+ * @param {string} t - Input Content
10
+ * @param {object} provider - Third-party JSON Parser
11
+ * @returns {object} ADOFAI File Object
12
+ */
13
+ static parseAsObject(t: string, provider?: any) {
14
+ return (typeof provider == 'undefined' ? StringParser : provider).parse(Parser.parseAsText(t));
15
+ }
16
+
17
+ /**
18
+ * @param {string} t - Input Content
19
+ * @returns {string} ADOFAI File Content
20
+ */
21
+ static parseAsText(t: string) {
22
+ return this.parseError(t);
23
+ }
24
+ }
25
+
26
+ export default Parser
@@ -1,167 +1,144 @@
1
- class ADOFAIX {
1
+ class StringParser {
2
2
  static parse(text: string | null, reviver?: (key: string, value: any) => any): any {
3
- if (text == null) return null
4
-
5
- const result = new ParserX(text).parseValue()
6
-
7
- // Apply reviver function if provided (similar to JSON.parse)
8
- if (typeof reviver === "function") {
9
- return this._applyReviver("", result, reviver)
10
- }
11
-
12
- return result
3
+ if (text == null) return null
4
+
5
+ const result = new ParserX(text).parseValue()
6
+
7
+ // Apply reviver function if provided (similar to JSON.parse)
8
+ if (typeof reviver === "function") {
9
+ return this._applyReviver("", result, reviver)
10
+ }
11
+
12
+ return result
13
13
  }
14
-
14
+
15
15
  static parsePartially(text: string | null, upToSection: string | null, reviver?: (key: string, value: any) => any): any {
16
- if (text == null) return null
17
-
18
- const result = new ParserX(text, upToSection).parseValue()
19
-
20
- if (typeof reviver === "function") {
21
- return this._applyReviver("", result, reviver)
22
- }
23
-
24
- return result
16
+ if (text == null) return null
17
+
18
+ const result = new ParserX(text, upToSection).parseValue()
19
+
20
+ if (typeof reviver === "function") {
21
+ return this._applyReviver("", result, reviver)
22
+ }
23
+
24
+ return result
25
25
  }
26
-
26
+
27
27
  static stringify(value: any, replacer?: (key: string, value: any) => any, space?: string | number): string {
28
- const serializer = new Serializer(replacer, space)
29
- return serializer.serialize(value)
28
+ const serializer = new Serializer(replacer, space)
29
+ return serializer.serialize(value)
30
30
  }
31
-
31
+
32
32
  // Helper method for reviver function
33
33
  static _applyReviver(key: string, value: any, reviver: (key: string, value: any) => any): any {
34
- if (value && typeof value === "object") {
35
- if (Array.isArray(value)) {
36
- const arrValue = value as any[];
37
- for (let i = 0; i < arrValue.length; i++) {
38
- arrValue[i] = this._applyReviver(i.toString(), arrValue[i], reviver)
39
- }
40
- } else {
41
- const objValue = value as Record<string, any>;
42
- for (const prop in objValue) {
43
- if (Object.prototype.hasOwnProperty.call(objValue, prop)) {
44
- objValue[prop] = this._applyReviver(prop, objValue[prop], reviver)
34
+ if (value && typeof value === "object") {
35
+ if (Array.isArray(value)) {
36
+ const arrValue = value as any[];
37
+ for (let i = 0; i < arrValue.length; i++) {
38
+ arrValue[i] = this._applyReviver(i.toString(), arrValue[i], reviver)
39
+ }
40
+ } else {
41
+ const objValue = value as Record<string, any>;
42
+ for (const prop in objValue) {
43
+ if (Object.prototype.hasOwnProperty.call(objValue, prop)) {
44
+ objValue[prop] = this._applyReviver(prop, objValue[prop], reviver)
45
+ }
46
+ }
45
47
  }
46
- }
47
48
  }
48
- }
49
- return reviver(key, value)
49
+ return reviver(key, value)
50
50
  }
51
- }
52
-
53
- class ParserX {
51
+ }
52
+
53
+ class ParserX {
54
54
  static WHITE_SPACE = " \t\n\r\uFEFF"
55
55
  static WORD_BREAK = ' \t\n\r{}[],:\"'
56
-
56
+
57
57
  static TOKEN = {
58
- NONE: 0,
59
- CURLY_OPEN: 1,
60
- CURLY_CLOSE: 2,
61
- SQUARED_OPEN: 3,
62
- SQUARED_CLOSE: 4,
63
- COLON: 5,
64
- COMMA: 6,
65
- STRING: 7,
66
- NUMBER: 8,
67
- TRUE: 9,
68
- FALSE: 10,
69
- NULL: 11,
58
+ NONE: 0,
59
+ CURLY_OPEN: 1,
60
+ CURLY_CLOSE: 2,
61
+ SQUARED_OPEN: 3,
62
+ SQUARED_CLOSE: 4,
63
+ COLON: 5,
64
+ COMMA: 6,
65
+ STRING: 7,
66
+ NUMBER: 8,
67
+ TRUE: 9,
68
+ FALSE: 10,
69
+ NULL: 11,
70
70
  }
71
-
71
+
72
72
  private json: string;
73
73
  private position: number;
74
74
  private endSection: string | null;
75
-
75
+
76
76
  constructor(jsonString: string, endSection: string | null = null) {
77
- this.json = jsonString
78
- this.position = 0
79
- this.endSection = endSection
80
-
81
- // Skip BOM if present
82
- if (this.peek() === 0xfeff) {
83
- this.read()
84
- }
77
+ this.json = jsonString
78
+ this.position = 0
79
+ this.endSection = endSection
80
+
81
+ // Skip BOM if present
82
+ if (this.peek() === 0xfeff) {
83
+ this.read()
84
+ }
85
85
  }
86
-
86
+
87
87
  parseValue(): any {
88
- return this.parseByToken(this.nextToken)
88
+ return this.parseByToken(this.nextToken)
89
89
  }
90
-
90
+
91
91
  parseObject(): Record<string, any> | null {
92
- const obj: Record<string, any> = {}
93
- this.read() // consume '{'
94
-
95
- while (true) {
96
- let nextToken
97
- do {
98
- nextToken = this.nextToken
99
- if (nextToken === ParserX.TOKEN.NONE) {
100
- return null
101
- }
102
- if (nextToken === ParserX.TOKEN.CURLY_CLOSE) {
103
- return obj
104
- }
105
- } while (nextToken === ParserX.TOKEN.COMMA)
106
-
107
- // Rest of the parser implementation would go here
108
- // This is a placeholder for the remaining parser code
109
- }
92
+ const obj: Record<string, any> = {}
93
+ this.read() // consume '{'
94
+
95
+ while (true) {
96
+ let nextToken
97
+ do {
98
+ nextToken = this.nextToken
99
+ if (nextToken === ParserX.TOKEN.NONE) {
100
+ return null
101
+ }
102
+ if (nextToken === ParserX.TOKEN.CURLY_CLOSE) {
103
+ return obj
104
+ }
105
+ } while (nextToken === ParserX.TOKEN.COMMA)
106
+
107
+ // Rest of the parser implementation would go here
108
+ // This is a placeholder for the remaining parser code
109
+ }
110
110
  }
111
111
 
112
112
  // Placeholder for other methods that would be in the Parser class
113
113
  private get nextToken(): number {
114
- // Implementation would go here
115
- return 0;
114
+ // Implementation would go here
115
+ return 0;
116
116
  }
117
117
 
118
118
  private read(): number {
119
- // Implementation would go here
120
- return 0;
119
+ // Implementation would go here
120
+ return 0;
121
121
  }
122
122
 
123
123
  private peek(): number {
124
- // Implementation would go here
125
- return 0;
124
+ // Implementation would go here
125
+ return 0;
126
126
  }
127
127
 
128
128
  private parseByToken(token: number): any {
129
- // Implementation would go here
130
- return null;
129
+ // Implementation would go here
130
+ return null;
131
131
  }
132
- }
132
+ }
133
133
 
134
- class Serializer {
134
+ class Serializer {
135
135
  constructor(replacer?: (key: string, value: any) => any, space?: string | number) {
136
- // Implementation would go here
136
+ // Implementation would go here
137
137
  }
138
138
 
139
139
  serialize(value: any): string {
140
- // Implementation would go here
141
- return "";
142
- }
143
- }
144
-
145
- class StringParser {
146
- static parseError(f: string) {
147
- return f;
148
- }
149
-
150
- /**
151
- * @param {string} t - Input Content
152
- * @param {object} provider - Third-party JSON Parser
153
- * @returns {object} ADOFAI File Object
154
- */
155
- static parseAsObject(t: string, provider?: any) {
156
- return (typeof provider == 'undefined' ? ADOFAIX : provider).parse(StringParser.parseAsText(t));
157
- }
158
-
159
- /**
160
- * @param {string} t - Input Content
161
- * @returns {string} ADOFAI File Content
162
- */
163
- static parseAsText(t: string) {
164
- return this.parseError(t);
140
+ // Implementation would go here
141
+ return "";
165
142
  }
166
143
  }
167
144
 
package/src/parser.ts CHANGED
@@ -1,4 +1,7 @@
1
- import StringParser from "./parser/StringParser";
1
+ import Parser from "./parser/Parser";
2
2
  import BufferParser from './parser/BufferParser';
3
+ import ArrayBufferParser from "./parser/ArrayBufferParser";
4
+ import StringParser from "./parser/StringParser";
3
5
 
4
- export {StringParser, BufferParser}
6
+ export {StringParser, BufferParser, ArrayBufferParser}
7
+ export default Parser;
@@ -1,7 +1,7 @@
1
1
  import { AdofaiEvent, LevelOptions, EventCallback, GuidCallback, Tile, ParseProvider } from './interfaces';
2
2
  import pathData from '../pathdata';
3
3
  import exportAsADOFAI from '../format'
4
- import {StringParser} from '../parser';
4
+ import Parser from '../parser';
5
5
  import effectProcessor from '../effectProcessor';
6
6
  import * as presets from '../presets';
7
7
 
@@ -40,7 +40,7 @@ export class Level {
40
40
  switch (typeof opt) {
41
41
  case 'string':
42
42
  try {
43
- options = StringParser.parseAsObject(opt, this._provider);
43
+ options = Parser.parseAsObject(opt, this._provider);
44
44
  } catch (e) {
45
45
  reject(e);
46
46
  return;
@@ -4,8 +4,8 @@ export interface AdofaiEvent {
4
4
  }
5
5
 
6
6
  export interface LevelOptions {
7
- pathData: string;
8
- angleData: number[];
7
+ pathData?: string;
8
+ angleData?: number[];
9
9
  actions: AdofaiEvent[];
10
10
  settings: Record<string, any>;
11
11
  decorations: AdofaiEvent[];
package/test/index.html CHANGED
@@ -1,7 +1,7 @@
1
1
  <input type="file" id="inputFile">
2
2
  <button id="export">Export as ADOFAI</button>
3
- <script src="../dist/adofai.min.js"></script>
4
- <script>
3
+ <script type="module">
4
+ import * as ADOFAI from '../dist/index.js'
5
5
  let fl, reader;
6
6
  document.querySelector('#inputFile').addEventListener('change', f => {
7
7
  fl = f.target.files[0];