rajt 0.0.23 → 0.0.24

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,7 +1,7 @@
1
1
  {
2
2
  "name": "rajt",
3
3
  "description": "A serverless bundler layer, fully typed for AWS Lambda (Node.js and LLRT) and Cloudflare Workers.",
4
- "version": "0.0.23",
4
+ "version": "0.0.24",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "exports": {
@@ -2,38 +2,43 @@ import type { SchemaStructure } from './types'
2
2
  import getLength from '../utils/lenght'
3
3
 
4
4
  export default class Compact {
5
+ static #typeRegex: RegExp
6
+ static #reverseTypeRegex: RegExp
7
+ static #reverseTypeMap: Record<string, string>
5
8
  static #typeMap: Record<string, string> = {
9
+ // Boolean
10
+ 'true': 'T',
11
+ 'false': 'F',
6
12
  // Null
7
- 'null,': 'N,',
8
- ',null': ',N',
9
- 'null]': 'N]',
10
- // True
11
- 'true,': 'T,',
12
- ',true': ',T',
13
- 'true]': 'T]',
14
- // False
15
- 'false,': 'F,',
16
- ',false': ',F',
17
- 'false]': 'F]',
13
+ 'null': 'N',
18
14
  // Array
19
- '[],': 'A,',
20
- ',[]': ',A',
21
- '[]]': 'A]',
15
+ '[]': 'A',
22
16
  // Object
23
- '{},': 'O,',
24
- ',{}': ',O',
25
- '{}]': 'O]'
17
+ '{}': 'O',
18
+ // Commons
19
+ '["0"]': 'A0',
20
+ '["1"]': 'A1',
21
+ '["true"]': 'A2',
22
+ '["false"]': 'A3',
23
+ '"true"': 'T1',
24
+ '"false"': 'T0',
25
+ }
26
+
27
+ static {
28
+ this.#reverseTypeMap = Object.fromEntries(Object.entries(this.#typeMap).map(([k, v]) => [v, k]))
29
+ this.#typeRegex = this.#mapRegex(Object.keys(this.#typeMap))
30
+ this.#reverseTypeRegex = this.#mapRegex(Object.keys(this.#reverseTypeMap))
26
31
  }
27
32
 
28
33
  static encode(obj: any, schema: SchemaStructure): string {
29
34
  const seen: any[] = []
30
- return this.replaceTypes(
31
- JSON.stringify(this.zip(obj, schema, seen)).replace(/(,|\[)"(\^\d+)"(\]|,|$)/g, '$1$2$3')
35
+ return this.#minify(
36
+ JSON.stringify(this.zip(obj, schema, seen))
37
+ .replace(/"\^(\d+)"/g, '^$1')
32
38
  .replace(/"/g, '~TDQ~')
33
39
  .replace(/'/g, '"')
34
40
  .replace(/~TDQ~/g, "'")
35
- .replace(/\\'/g, "^'"),
36
- this.#typeMap
41
+ .replace(/\\'/g, "^'")
37
42
  )
38
43
  }
39
44
 
@@ -47,16 +52,16 @@ export default class Compact {
47
52
  }
48
53
 
49
54
  static decode<T = any>(val: string, schema: SchemaStructure): T {
50
- if (!val) return val as T
55
+ if (!val || typeof val !== 'string') return val as T
51
56
 
52
- val = this.replaceTypes(val, this.reverseMap(this.#typeMap))
53
- .replace(/"/g, '~TSQ~')
54
- .replace(/'/g, '"')
55
- .replace(/~TSQ~/g, "'")
56
- .replace(/\^"/g, '\\"')
57
- .replace(/(,|\[)(\^\d+)(\]|,|$)/g, '$1"$2"$3')
58
-
59
- return this.withSchema(this.unzip(JSON.parse(val)), schema) as T
57
+ return this.withSchema(this.unzip(JSON.parse(
58
+ this.#deminify(val)
59
+ .replace(/"/g, '~TSQ~')
60
+ .replace(/'/g, '"')
61
+ .replace(/~TSQ~/g, "'")
62
+ .replace(/\^"/g, '\\"')
63
+ .replace(/(?<=[,{\[]|^)(\^\d+)(?=[,\]}[]|$)/g, '"$1"')
64
+ )), schema) as T
60
65
  }
61
66
 
62
67
  static zip(obj: any, schema: SchemaStructure, seen: any[]): any[] {
@@ -75,25 +80,30 @@ export default class Compact {
75
80
  })
76
81
  }
77
82
 
78
- static unzip(array: any[], seen: any[] = [], deep = false): any[] {
79
- return array.map(item => {
80
- const length = getLength(item)
83
+ static unzip(val: any, seen: any[] = [], deep = false): any[] {
84
+ const type = typeof val
85
+ const length = getLength(val, type)
81
86
 
82
- if ([null, true, false].includes(item) || typeof item !== 'object' && length < 2)
83
- return item
87
+ if ([null, true, false].includes(val) || type != 'object' && length < 2)
88
+ return val
84
89
 
85
- if (Array.isArray(item))
86
- return this.unzip(item, seen, true)
90
+ if (Array.isArray(val))
91
+ return val.map(item => this.unzip(item, seen, deep))
87
92
 
88
- if (typeof item === 'string' && item.startsWith('^')) {
89
- const pos = parseInt(item.slice(1), 10)
90
- const val = seen[pos]
91
- return deep || (val && !`${val}`.startsWith('^')) ? val : item
92
- }
93
+ if (type == 'object') {
94
+ for (const key in val)
95
+ val[key] = this.unzip(val[key], seen)
93
96
 
94
- seen.push(item)
95
- return item
96
- })
97
+ return val
98
+ }
99
+
100
+ if (type == 'string' && val.startsWith('^')) {
101
+ const item = seen[parseInt(val.slice(1), 10)]
102
+ return item ? item : val
103
+ }
104
+
105
+ seen.push(val)
106
+ return val
97
107
  }
98
108
 
99
109
  static withSchema(value: any[], keys: any[]): any {
@@ -108,14 +118,14 @@ export default class Compact {
108
118
  static entry(key: any, value: any): any {
109
119
  if (!key) return undefined
110
120
 
111
- if (typeof key === 'string')
121
+ if (typeof key == 'string')
112
122
  return [key, value]
113
123
 
114
124
  const mainKey = Object.keys(key)[0]
115
125
  const subKeys = key[mainKey]
116
126
 
117
127
  if (Array.isArray(value)) {
118
- if (value.length === 0)
128
+ if (value.length < 1)
119
129
  return [mainKey, []]
120
130
 
121
131
  return Array.isArray(value[0])
@@ -127,9 +137,19 @@ export default class Compact {
127
137
  }
128
138
 
129
139
  static memo(val: any, seen: any[]): any {
130
- const length = getLength(val)
131
- // TODO: may be incompatible with empty objects or arrays
132
- if (typeof val !== 'object' && length < 2) return val
140
+ if (Array.isArray(val))
141
+ return val.map(item => this.memo(item, seen))
142
+
143
+ const type = typeof val
144
+ if (type == 'object' && val != null) {
145
+ for (const key in val)
146
+ val[key] = this.memo(val[key], seen)
147
+
148
+ return val
149
+ }
150
+ const length = getLength(val, type)
151
+
152
+ if (type !== 'object' && length < 2) return val
133
153
 
134
154
  const index = seen.indexOf(val)
135
155
  if (index !== -1)
@@ -139,11 +159,16 @@ export default class Compact {
139
159
  return val
140
160
  }
141
161
 
142
- static replaceTypes(str: string, map: Record<string, string>) {
143
- return Object.entries(map).reduce((s, [from, to]) => s.replaceAll(from, to), str)
162
+ static #mapRegex(keys: string[]) {
163
+ keys = keys.sort((a, b) => b.length - a.length).map(k => k.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
164
+ return new RegExp(`(?<![^\\s,\\[\\{:])(${keys.join('|')})(?![^\\s,\\]\\}:])`, 'g')
165
+ }
166
+
167
+ static #minify(val: string): string {
168
+ return val.replace(this.#typeRegex, match => this.#typeMap[match])
144
169
  }
145
170
 
146
- static reverseMap(map: Record<string, string>): Record<string, string> {
147
- return Object.fromEntries(Object.entries(map).map(([k, v]) => [v, k]))
171
+ static #deminify(val: string): string {
172
+ return val.replace(this.#reverseTypeRegex, match => this.#reverseTypeMap[match])
148
173
  }
149
174
  }
@@ -1,5 +1,5 @@
1
- export default function getLength(item: any): number {
2
- const type = typeof item
1
+ export default function getLength(item: any, type?: string): number {
2
+ if (!type) type = typeof item
3
3
 
4
4
  switch (type) {
5
5
  case 'string':