titanpl 7.0.0-beta → 7.0.0
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 +2 -6
- package/packages/cli/package.json +4 -4
- package/packages/core-source/LICENSE +15 -0
- package/packages/core-source/README.md +128 -0
- package/packages/core-source/V8_SERIALIZATION.md +125 -0
- package/packages/core-source/configure.js +50 -0
- package/packages/core-source/globals.d.ts +2238 -0
- package/packages/core-source/index.d.ts +515 -0
- package/packages/core-source/index.js +639 -0
- package/packages/core-source/jsconfig.json +12 -0
- package/packages/core-source/mkctx.config.json +7 -0
- package/packages/core-source/native/Cargo.lock +1559 -0
- package/packages/core-source/native/Cargo.toml +30 -0
- package/packages/core-source/native/src/crypto_impl.rs +139 -0
- package/packages/core-source/native/src/lib.rs +702 -0
- package/packages/core-source/native/src/storage_impl.rs +73 -0
- package/packages/core-source/native/src/v8_impl.rs +93 -0
- package/packages/core-source/package-lock.json +1464 -0
- package/packages/core-source/package.json +53 -0
- package/packages/core-source/tests/buffer.test.js +78 -0
- package/packages/core-source/tests/cookies.test.js +117 -0
- package/packages/core-source/tests/crypto.test.js +142 -0
- package/packages/core-source/tests/fs.test.js +176 -0
- package/packages/core-source/tests/ls.test.js +149 -0
- package/packages/core-source/tests/net.test.js +84 -0
- package/packages/core-source/tests/os.test.js +81 -0
- package/packages/core-source/tests/path.test.js +102 -0
- package/packages/core-source/tests/response.test.js +146 -0
- package/packages/core-source/tests/session.test.js +110 -0
- package/packages/core-source/tests/setup.js +325 -0
- package/packages/core-source/tests/time.test.js +57 -0
- package/packages/core-source/tests/url.test.js +82 -0
- package/packages/core-source/titan-ext.d.ts +2 -0
- package/packages/core-source/titan.json +9 -0
- package/packages/core-source/vitest.config.js +8 -0
- package/packages/engine-darwin-arm64/package.json +1 -1
- package/packages/engine-linux-x64/package.json +1 -1
- package/packages/engine-win32-x64/bin/titan-server.exe +0 -0
- package/packages/engine-win32-x64/package.json +1 -1
- package/packages/native/index.d.ts +16 -1
- package/packages/native/index.js +6 -0
- package/packages/native/package.json +2 -2
- package/packages/native/t.native.d.ts +77 -0
- package/packages/packet/index.js +94 -102
- package/packages/packet/package.json +1 -1
- package/packages/route/package.json +1 -1
- package/packages/sdk/package.json +1 -1
- package/templates/common/_tanfig.json +4 -2
- package/templates/extension/package.json +2 -2
- package/templates/js/package.json +8 -8
- package/templates/rust-js/package.json +5 -5
- package/templates/rust-ts/package.json +5 -5
- package/templates/ts/package.json +8 -8
- package/packages/packet/node_modules/typescript/LICENSE.txt +0 -55
- package/packages/packet/node_modules/typescript/README.md +0 -50
- package/packages/packet/node_modules/typescript/SECURITY.md +0 -41
- package/packages/packet/node_modules/typescript/ThirdPartyNoticeText.txt +0 -193
- package/packages/packet/node_modules/typescript/bin/tsc +0 -2
- package/packages/packet/node_modules/typescript/bin/tsserver +0 -2
- package/packages/packet/node_modules/typescript/lib/_tsc.js +0 -133818
- package/packages/packet/node_modules/typescript/lib/_tsserver.js +0 -659
- package/packages/packet/node_modules/typescript/lib/_typingsInstaller.js +0 -222
- package/packages/packet/node_modules/typescript/lib/cs/diagnosticMessages.generated.json +0 -2122
- package/packages/packet/node_modules/typescript/lib/de/diagnosticMessages.generated.json +0 -2122
- package/packages/packet/node_modules/typescript/lib/es/diagnosticMessages.generated.json +0 -2122
- package/packages/packet/node_modules/typescript/lib/fr/diagnosticMessages.generated.json +0 -2122
- package/packages/packet/node_modules/typescript/lib/it/diagnosticMessages.generated.json +0 -2122
- package/packages/packet/node_modules/typescript/lib/ja/diagnosticMessages.generated.json +0 -2122
- package/packages/packet/node_modules/typescript/lib/ko/diagnosticMessages.generated.json +0 -2122
- package/packages/packet/node_modules/typescript/lib/lib.d.ts +0 -22
- package/packages/packet/node_modules/typescript/lib/lib.decorators.d.ts +0 -384
- package/packages/packet/node_modules/typescript/lib/lib.decorators.legacy.d.ts +0 -22
- package/packages/packet/node_modules/typescript/lib/lib.dom.asynciterable.d.ts +0 -41
- package/packages/packet/node_modules/typescript/lib/lib.dom.d.ts +0 -39429
- package/packages/packet/node_modules/typescript/lib/lib.dom.iterable.d.ts +0 -571
- package/packages/packet/node_modules/typescript/lib/lib.es2015.collection.d.ts +0 -147
- package/packages/packet/node_modules/typescript/lib/lib.es2015.core.d.ts +0 -597
- package/packages/packet/node_modules/typescript/lib/lib.es2015.d.ts +0 -28
- package/packages/packet/node_modules/typescript/lib/lib.es2015.generator.d.ts +0 -77
- package/packages/packet/node_modules/typescript/lib/lib.es2015.iterable.d.ts +0 -605
- package/packages/packet/node_modules/typescript/lib/lib.es2015.promise.d.ts +0 -81
- package/packages/packet/node_modules/typescript/lib/lib.es2015.proxy.d.ts +0 -128
- package/packages/packet/node_modules/typescript/lib/lib.es2015.reflect.d.ts +0 -144
- package/packages/packet/node_modules/typescript/lib/lib.es2015.symbol.d.ts +0 -46
- package/packages/packet/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts +0 -326
- package/packages/packet/node_modules/typescript/lib/lib.es2016.array.include.d.ts +0 -116
- package/packages/packet/node_modules/typescript/lib/lib.es2016.d.ts +0 -21
- package/packages/packet/node_modules/typescript/lib/lib.es2016.full.d.ts +0 -23
- package/packages/packet/node_modules/typescript/lib/lib.es2016.intl.d.ts +0 -31
- package/packages/packet/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts +0 -21
- package/packages/packet/node_modules/typescript/lib/lib.es2017.d.ts +0 -26
- package/packages/packet/node_modules/typescript/lib/lib.es2017.date.d.ts +0 -31
- package/packages/packet/node_modules/typescript/lib/lib.es2017.full.d.ts +0 -23
- package/packages/packet/node_modules/typescript/lib/lib.es2017.intl.d.ts +0 -44
- package/packages/packet/node_modules/typescript/lib/lib.es2017.object.d.ts +0 -49
- package/packages/packet/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts +0 -135
- package/packages/packet/node_modules/typescript/lib/lib.es2017.string.d.ts +0 -45
- package/packages/packet/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts +0 -53
- package/packages/packet/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts +0 -77
- package/packages/packet/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts +0 -53
- package/packages/packet/node_modules/typescript/lib/lib.es2018.d.ts +0 -24
- package/packages/packet/node_modules/typescript/lib/lib.es2018.full.d.ts +0 -24
- package/packages/packet/node_modules/typescript/lib/lib.es2018.intl.d.ts +0 -83
- package/packages/packet/node_modules/typescript/lib/lib.es2018.promise.d.ts +0 -30
- package/packages/packet/node_modules/typescript/lib/lib.es2018.regexp.d.ts +0 -37
- package/packages/packet/node_modules/typescript/lib/lib.es2019.array.d.ts +0 -79
- package/packages/packet/node_modules/typescript/lib/lib.es2019.d.ts +0 -24
- package/packages/packet/node_modules/typescript/lib/lib.es2019.full.d.ts +0 -24
- package/packages/packet/node_modules/typescript/lib/lib.es2019.intl.d.ts +0 -23
- package/packages/packet/node_modules/typescript/lib/lib.es2019.object.d.ts +0 -33
- package/packages/packet/node_modules/typescript/lib/lib.es2019.string.d.ts +0 -37
- package/packages/packet/node_modules/typescript/lib/lib.es2019.symbol.d.ts +0 -24
- package/packages/packet/node_modules/typescript/lib/lib.es2020.bigint.d.ts +0 -765
- package/packages/packet/node_modules/typescript/lib/lib.es2020.d.ts +0 -27
- package/packages/packet/node_modules/typescript/lib/lib.es2020.date.d.ts +0 -42
- package/packages/packet/node_modules/typescript/lib/lib.es2020.full.d.ts +0 -24
- package/packages/packet/node_modules/typescript/lib/lib.es2020.intl.d.ts +0 -474
- package/packages/packet/node_modules/typescript/lib/lib.es2020.number.d.ts +0 -28
- package/packages/packet/node_modules/typescript/lib/lib.es2020.promise.d.ts +0 -47
- package/packages/packet/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts +0 -99
- package/packages/packet/node_modules/typescript/lib/lib.es2020.string.d.ts +0 -44
- package/packages/packet/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts +0 -41
- package/packages/packet/node_modules/typescript/lib/lib.es2021.d.ts +0 -23
- package/packages/packet/node_modules/typescript/lib/lib.es2021.full.d.ts +0 -24
- package/packages/packet/node_modules/typescript/lib/lib.es2021.intl.d.ts +0 -166
- package/packages/packet/node_modules/typescript/lib/lib.es2021.promise.d.ts +0 -48
- package/packages/packet/node_modules/typescript/lib/lib.es2021.string.d.ts +0 -33
- package/packages/packet/node_modules/typescript/lib/lib.es2021.weakref.d.ts +0 -78
- package/packages/packet/node_modules/typescript/lib/lib.es2022.array.d.ts +0 -121
- package/packages/packet/node_modules/typescript/lib/lib.es2022.d.ts +0 -25
- package/packages/packet/node_modules/typescript/lib/lib.es2022.error.d.ts +0 -75
- package/packages/packet/node_modules/typescript/lib/lib.es2022.full.d.ts +0 -24
- package/packages/packet/node_modules/typescript/lib/lib.es2022.intl.d.ts +0 -145
- package/packages/packet/node_modules/typescript/lib/lib.es2022.object.d.ts +0 -26
- package/packages/packet/node_modules/typescript/lib/lib.es2022.regexp.d.ts +0 -39
- package/packages/packet/node_modules/typescript/lib/lib.es2022.string.d.ts +0 -25
- package/packages/packet/node_modules/typescript/lib/lib.es2023.array.d.ts +0 -924
- package/packages/packet/node_modules/typescript/lib/lib.es2023.collection.d.ts +0 -21
- package/packages/packet/node_modules/typescript/lib/lib.es2023.d.ts +0 -22
- package/packages/packet/node_modules/typescript/lib/lib.es2023.full.d.ts +0 -24
- package/packages/packet/node_modules/typescript/lib/lib.es2023.intl.d.ts +0 -56
- package/packages/packet/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts +0 -65
- package/packages/packet/node_modules/typescript/lib/lib.es2024.collection.d.ts +0 -29
- package/packages/packet/node_modules/typescript/lib/lib.es2024.d.ts +0 -26
- package/packages/packet/node_modules/typescript/lib/lib.es2024.full.d.ts +0 -24
- package/packages/packet/node_modules/typescript/lib/lib.es2024.object.d.ts +0 -29
- package/packages/packet/node_modules/typescript/lib/lib.es2024.promise.d.ts +0 -35
- package/packages/packet/node_modules/typescript/lib/lib.es2024.regexp.d.ts +0 -25
- package/packages/packet/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts +0 -68
- package/packages/packet/node_modules/typescript/lib/lib.es2024.string.d.ts +0 -29
- package/packages/packet/node_modules/typescript/lib/lib.es5.d.ts +0 -4601
- package/packages/packet/node_modules/typescript/lib/lib.es6.d.ts +0 -23
- package/packages/packet/node_modules/typescript/lib/lib.esnext.array.d.ts +0 -35
- package/packages/packet/node_modules/typescript/lib/lib.esnext.collection.d.ts +0 -96
- package/packages/packet/node_modules/typescript/lib/lib.esnext.d.ts +0 -29
- package/packages/packet/node_modules/typescript/lib/lib.esnext.decorators.d.ts +0 -28
- package/packages/packet/node_modules/typescript/lib/lib.esnext.disposable.d.ts +0 -193
- package/packages/packet/node_modules/typescript/lib/lib.esnext.error.d.ts +0 -24
- package/packages/packet/node_modules/typescript/lib/lib.esnext.float16.d.ts +0 -445
- package/packages/packet/node_modules/typescript/lib/lib.esnext.full.d.ts +0 -24
- package/packages/packet/node_modules/typescript/lib/lib.esnext.intl.d.ts +0 -21
- package/packages/packet/node_modules/typescript/lib/lib.esnext.iterator.d.ts +0 -148
- package/packages/packet/node_modules/typescript/lib/lib.esnext.promise.d.ts +0 -34
- package/packages/packet/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts +0 -25
- package/packages/packet/node_modules/typescript/lib/lib.scripthost.d.ts +0 -322
- package/packages/packet/node_modules/typescript/lib/lib.webworker.asynciterable.d.ts +0 -41
- package/packages/packet/node_modules/typescript/lib/lib.webworker.d.ts +0 -13150
- package/packages/packet/node_modules/typescript/lib/lib.webworker.importscripts.d.ts +0 -23
- package/packages/packet/node_modules/typescript/lib/lib.webworker.iterable.d.ts +0 -340
- package/packages/packet/node_modules/typescript/lib/pl/diagnosticMessages.generated.json +0 -2122
- package/packages/packet/node_modules/typescript/lib/pt-br/diagnosticMessages.generated.json +0 -2122
- package/packages/packet/node_modules/typescript/lib/ru/diagnosticMessages.generated.json +0 -2122
- package/packages/packet/node_modules/typescript/lib/tr/diagnosticMessages.generated.json +0 -2122
- package/packages/packet/node_modules/typescript/lib/tsc.js +0 -8
- package/packages/packet/node_modules/typescript/lib/tsserver.js +0 -8
- package/packages/packet/node_modules/typescript/lib/tsserverlibrary.d.ts +0 -17
- package/packages/packet/node_modules/typescript/lib/tsserverlibrary.js +0 -21
- package/packages/packet/node_modules/typescript/lib/typesMap.json +0 -497
- package/packages/packet/node_modules/typescript/lib/typescript.d.ts +0 -11437
- package/packages/packet/node_modules/typescript/lib/typescript.js +0 -200276
- package/packages/packet/node_modules/typescript/lib/typingsInstaller.js +0 -8
- package/packages/packet/node_modules/typescript/lib/watchGuard.js +0 -53
- package/packages/packet/node_modules/typescript/lib/zh-cn/diagnosticMessages.generated.json +0 -2122
- package/packages/packet/node_modules/typescript/lib/zh-tw/diagnosticMessages.generated.json +0 -2122
- package/packages/packet/node_modules/typescript/package.json +0 -120
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tests/setup.js
|
|
3
|
+
*
|
|
4
|
+
* Emulates Rust native functions for testing.
|
|
5
|
+
* Equivalent to what @t8n/micro-gravity/setup would do.
|
|
6
|
+
*
|
|
7
|
+
* MOCKED:
|
|
8
|
+
* - DB (PostgreSQL connection) - No way to test without a real DB
|
|
9
|
+
*
|
|
10
|
+
* EMULATED (JS implementation that simulates Rust behavior):
|
|
11
|
+
* - fs_* (uses Node.js fs)
|
|
12
|
+
* - crypto_* (uses Node.js crypto)
|
|
13
|
+
* - ls_* (uses in-memory Map)
|
|
14
|
+
* - session_* (uses in-memory Map)
|
|
15
|
+
* - os_*, net_*, proc_*, time_*, path_cwd
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { vi } from 'vitest';
|
|
19
|
+
import * as nodeFs from 'node:fs';
|
|
20
|
+
import * as nodePath from 'node:path';
|
|
21
|
+
import * as nodeCrypto from 'node:crypto';
|
|
22
|
+
import * as nodeOs from 'node:os';
|
|
23
|
+
|
|
24
|
+
// In-memory storage for ls and session
|
|
25
|
+
const localStorage = new Map();
|
|
26
|
+
const sessionStorage = new Map();
|
|
27
|
+
|
|
28
|
+
// Initialize global `t` object with native functions
|
|
29
|
+
globalThis.t = globalThis.t || {};
|
|
30
|
+
globalThis.t["@titanpl/core"] = globalThis.t["@titanpl/core"] || {};
|
|
31
|
+
globalThis.t.native = globalThis.t.native || {};
|
|
32
|
+
globalThis.t.core = globalThis.t.core || {};
|
|
33
|
+
|
|
34
|
+
const ext = globalThis.t["@titanpl/core"];
|
|
35
|
+
|
|
36
|
+
// ============================================
|
|
37
|
+
// FILE SYSTEM - Emulation using Node.js fs
|
|
38
|
+
// ============================================
|
|
39
|
+
|
|
40
|
+
ext.fs_read_file = (path) => {
|
|
41
|
+
try {
|
|
42
|
+
return nodeFs.readFileSync(path, 'utf-8');
|
|
43
|
+
} catch (e) {
|
|
44
|
+
return `ERROR: ${e.message}`;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
ext.fs_write_file = (path, content) => {
|
|
49
|
+
nodeFs.writeFileSync(path, content, 'utf-8');
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
ext.fs_readdir = (path) => {
|
|
53
|
+
try {
|
|
54
|
+
return JSON.stringify(nodeFs.readdirSync(path));
|
|
55
|
+
} catch {
|
|
56
|
+
return '[]';
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
ext.fs_mkdir = (path) => {
|
|
61
|
+
nodeFs.mkdirSync(path, { recursive: true });
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
ext.fs_exists = (path) => {
|
|
65
|
+
return nodeFs.existsSync(path);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
ext.fs_stat = (path) => {
|
|
69
|
+
try {
|
|
70
|
+
const stat = nodeFs.statSync(path);
|
|
71
|
+
return JSON.stringify({
|
|
72
|
+
size: stat.size,
|
|
73
|
+
isFile: stat.isFile(),
|
|
74
|
+
isDir: stat.isDirectory(),
|
|
75
|
+
modified: stat.mtimeMs
|
|
76
|
+
});
|
|
77
|
+
} catch {
|
|
78
|
+
return '{}';
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
ext.fs_remove = (path) => {
|
|
83
|
+
try {
|
|
84
|
+
const stat = nodeFs.statSync(path);
|
|
85
|
+
if (stat.isDirectory()) {
|
|
86
|
+
nodeFs.rmSync(path, { recursive: true });
|
|
87
|
+
} else {
|
|
88
|
+
nodeFs.unlinkSync(path);
|
|
89
|
+
}
|
|
90
|
+
} catch { }
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
ext.path_cwd = () => process.cwd();
|
|
94
|
+
|
|
95
|
+
// ============================================
|
|
96
|
+
// CRYPTO - Emulation using Node.js crypto
|
|
97
|
+
// ============================================
|
|
98
|
+
|
|
99
|
+
ext.crypto_hash = (algo, data) => {
|
|
100
|
+
try {
|
|
101
|
+
const hash = nodeCrypto.createHash(algo);
|
|
102
|
+
hash.update(data);
|
|
103
|
+
return hash.digest('hex');
|
|
104
|
+
} catch (e) {
|
|
105
|
+
return `ERROR: ${e.message}`;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
ext.crypto_random_bytes = (size) => {
|
|
110
|
+
return nodeCrypto.randomBytes(size).toString('hex');
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
ext.crypto_uuid = () => {
|
|
114
|
+
return nodeCrypto.randomUUID();
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
ext.crypto_encrypt = (algo, jsonArgs) => {
|
|
118
|
+
try {
|
|
119
|
+
const { key, plaintext } = JSON.parse(jsonArgs);
|
|
120
|
+
const keyBuffer = Buffer.alloc(32);
|
|
121
|
+
Buffer.from(key).copy(keyBuffer);
|
|
122
|
+
const iv = nodeCrypto.randomBytes(12);
|
|
123
|
+
const cipher = nodeCrypto.createCipheriv('aes-256-gcm', keyBuffer, iv);
|
|
124
|
+
let encrypted = cipher.update(plaintext, 'utf8', 'hex');
|
|
125
|
+
encrypted += cipher.final('hex');
|
|
126
|
+
const authTag = cipher.getAuthTag().toString('hex');
|
|
127
|
+
return iv.toString('hex') + ':' + authTag + ':' + encrypted;
|
|
128
|
+
} catch (e) {
|
|
129
|
+
return `ERROR: ${e.message}`;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
ext.crypto_decrypt = (algo, jsonArgs) => {
|
|
134
|
+
try {
|
|
135
|
+
const { key, ciphertext } = JSON.parse(jsonArgs);
|
|
136
|
+
const [ivHex, authTagHex, encrypted] = ciphertext.split(':');
|
|
137
|
+
const keyBuffer = Buffer.alloc(32);
|
|
138
|
+
Buffer.from(key).copy(keyBuffer);
|
|
139
|
+
const iv = Buffer.from(ivHex, 'hex');
|
|
140
|
+
const authTag = Buffer.from(authTagHex, 'hex');
|
|
141
|
+
const decipher = nodeCrypto.createDecipheriv('aes-256-gcm', keyBuffer, iv);
|
|
142
|
+
decipher.setAuthTag(authTag);
|
|
143
|
+
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
|
|
144
|
+
decrypted += decipher.final('utf8');
|
|
145
|
+
return decrypted;
|
|
146
|
+
} catch (e) {
|
|
147
|
+
return `ERROR: ${e.message}`;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
ext.crypto_hash_keyed = (algo, jsonArgs) => {
|
|
152
|
+
try {
|
|
153
|
+
const { key, message } = JSON.parse(jsonArgs);
|
|
154
|
+
const hmac = nodeCrypto.createHmac(algo === 'sha256' ? 'sha256' : 'sha512', key);
|
|
155
|
+
hmac.update(message);
|
|
156
|
+
return hmac.digest('hex');
|
|
157
|
+
} catch (e) {
|
|
158
|
+
return `ERROR: ${e.message}`;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
ext.crypto_compare = (a, b) => {
|
|
163
|
+
return nodeCrypto.timingSafeEqual(Buffer.from(a), Buffer.from(b));
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
// ============================================
|
|
167
|
+
// LOCAL STORAGE - In-memory emulation
|
|
168
|
+
// ============================================
|
|
169
|
+
|
|
170
|
+
ext.ls_get = (key) => {
|
|
171
|
+
return localStorage.get(key) || '';
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
ext.ls_set = (key, value) => {
|
|
175
|
+
localStorage.set(key, value);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
ext.ls_remove = (key) => {
|
|
179
|
+
localStorage.delete(key);
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
ext.ls_clear = () => {
|
|
183
|
+
localStorage.clear();
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
ext.ls_keys = () => {
|
|
187
|
+
return JSON.stringify([...localStorage.keys()]);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// Simplified V8 serialization (uses JSON as fallback)
|
|
191
|
+
ext.serialize = (value) => {
|
|
192
|
+
try {
|
|
193
|
+
const json = JSON.stringify(value);
|
|
194
|
+
return new TextEncoder().encode(json);
|
|
195
|
+
} catch {
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
ext.deserialize = (bytes) => {
|
|
201
|
+
try {
|
|
202
|
+
const json = new TextDecoder().decode(bytes);
|
|
203
|
+
return JSON.parse(json);
|
|
204
|
+
} catch {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// ============================================
|
|
210
|
+
// SESSION - In-memory emulation
|
|
211
|
+
// ============================================
|
|
212
|
+
|
|
213
|
+
ext.session_get = (sid, key) => {
|
|
214
|
+
return sessionStorage.get(`${sid}:${key}`) || '';
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
ext.session_set = (sid, jsonArgs) => {
|
|
218
|
+
const { key, value } = JSON.parse(jsonArgs);
|
|
219
|
+
sessionStorage.set(`${sid}:${key}`, value);
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
ext.session_delete = (sid, key) => {
|
|
223
|
+
sessionStorage.delete(`${sid}:${key}`);
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
ext.session_clear = (sid) => {
|
|
227
|
+
for (const key of sessionStorage.keys()) {
|
|
228
|
+
if (key.startsWith(`${sid}:`)) {
|
|
229
|
+
sessionStorage.delete(key);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
// ============================================
|
|
235
|
+
// OS - Emulation using Node.js os
|
|
236
|
+
// ============================================
|
|
237
|
+
|
|
238
|
+
ext.os_info = () => {
|
|
239
|
+
return JSON.stringify({
|
|
240
|
+
platform: nodeOs.platform(),
|
|
241
|
+
cpus: nodeOs.cpus().length,
|
|
242
|
+
totalMemory: nodeOs.totalmem(),
|
|
243
|
+
freeMemory: nodeOs.freemem(),
|
|
244
|
+
tmpdir: nodeOs.tmpdir()
|
|
245
|
+
});
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// ============================================
|
|
249
|
+
// NET - Basic emulation
|
|
250
|
+
// ============================================
|
|
251
|
+
|
|
252
|
+
ext.net_resolve = (hostname) => {
|
|
253
|
+
return JSON.stringify(['127.0.0.1']);
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
ext.net_ip = () => {
|
|
257
|
+
const interfaces = nodeOs.networkInterfaces();
|
|
258
|
+
for (const name of Object.keys(interfaces)) {
|
|
259
|
+
for (const iface of interfaces[name]) {
|
|
260
|
+
if (iface.family === 'IPv4' && !iface.internal) {
|
|
261
|
+
return iface.address;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return '127.0.0.1';
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
// ============================================
|
|
269
|
+
// PROC - Basic emulation
|
|
270
|
+
// ============================================
|
|
271
|
+
|
|
272
|
+
ext.proc_info = () => {
|
|
273
|
+
return JSON.stringify({
|
|
274
|
+
pid: process.pid,
|
|
275
|
+
uptime: process.uptime()
|
|
276
|
+
});
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
ext.proc_run = (jsonArgs) => {
|
|
280
|
+
return JSON.stringify({ ok: false, error: 'Disabled in tests' });
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
ext.proc_kill = (pid) => {
|
|
284
|
+
return false;
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
ext.proc_list = () => {
|
|
288
|
+
return JSON.stringify([]);
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
// ============================================
|
|
292
|
+
// TIME
|
|
293
|
+
// ============================================
|
|
294
|
+
|
|
295
|
+
ext.time_sleep = (ms) => {
|
|
296
|
+
const end = Date.now() + ms;
|
|
297
|
+
while (Date.now() < end) { }
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
// ============================================
|
|
301
|
+
// DATABASE - MOCK (only real mock)
|
|
302
|
+
// ============================================
|
|
303
|
+
|
|
304
|
+
globalThis.t.db = {
|
|
305
|
+
connect: vi.fn().mockReturnValue({
|
|
306
|
+
query: vi.fn().mockResolvedValue({ rows: [] }),
|
|
307
|
+
execute: vi.fn().mockResolvedValue({ rowCount: 0 }),
|
|
308
|
+
close: vi.fn()
|
|
309
|
+
})
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
// ============================================
|
|
313
|
+
// Helpers to clear state between tests
|
|
314
|
+
// ============================================
|
|
315
|
+
|
|
316
|
+
export function clearStorage() {
|
|
317
|
+
localStorage.clear();
|
|
318
|
+
sessionStorage.clear();
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
import { beforeEach } from 'vitest';
|
|
322
|
+
|
|
323
|
+
beforeEach(() => {
|
|
324
|
+
clearStorage();
|
|
325
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tests/time.test.js
|
|
3
|
+
*
|
|
4
|
+
* Tests for the time module
|
|
5
|
+
* time.now() - Pure JS (Date.now())
|
|
6
|
+
* time.sleep() - Native emulated
|
|
7
|
+
*/
|
|
8
|
+
import { describe, it, expect } from 'vitest';
|
|
9
|
+
import { time } from '../index.js';
|
|
10
|
+
|
|
11
|
+
describe('time', () => {
|
|
12
|
+
describe('now()', () => {
|
|
13
|
+
it('should return current timestamp', () => {
|
|
14
|
+
const before = Date.now();
|
|
15
|
+
const result = time.now();
|
|
16
|
+
const after = Date.now();
|
|
17
|
+
|
|
18
|
+
expect(result).toBeGreaterThanOrEqual(before);
|
|
19
|
+
expect(result).toBeLessThanOrEqual(after);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should return number', () => {
|
|
23
|
+
expect(typeof time.now()).toBe('number');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should increment over time', async () => {
|
|
27
|
+
const first = time.now();
|
|
28
|
+
await new Promise(r => setTimeout(r, 10));
|
|
29
|
+
const second = time.now();
|
|
30
|
+
|
|
31
|
+
expect(second).toBeGreaterThan(first);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe('sleep()', () => {
|
|
36
|
+
it('should pause execution', () => {
|
|
37
|
+
const start = Date.now();
|
|
38
|
+
time.sleep(50);
|
|
39
|
+
const elapsed = Date.now() - start;
|
|
40
|
+
|
|
41
|
+
// Should have passed at least 40ms (margin of error)
|
|
42
|
+
expect(elapsed).toBeGreaterThanOrEqual(40);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should accept small values', () => {
|
|
46
|
+
expect(() => time.sleep(1)).not.toThrow();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should handle 0ms', () => {
|
|
50
|
+
const start = Date.now();
|
|
51
|
+
time.sleep(0);
|
|
52
|
+
const elapsed = Date.now() - start;
|
|
53
|
+
|
|
54
|
+
expect(elapsed).toBeLessThan(100);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tests/url.test.js
|
|
3
|
+
*
|
|
4
|
+
* Tests for the url module
|
|
5
|
+
* Pure JS API - uses native URL and URLSearchParams
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect } from 'vitest';
|
|
8
|
+
import { url } from '../index.js';
|
|
9
|
+
|
|
10
|
+
describe('url', () => {
|
|
11
|
+
describe('parse()', () => {
|
|
12
|
+
it('should parse complete URL', () => {
|
|
13
|
+
const parsed = url.parse('https://example.com:8080/path?query=value#hash');
|
|
14
|
+
|
|
15
|
+
expect(parsed.protocol).toBe('https:');
|
|
16
|
+
expect(parsed.hostname).toBe('example.com');
|
|
17
|
+
expect(parsed.port).toBe('8080');
|
|
18
|
+
expect(parsed.pathname).toBe('/path');
|
|
19
|
+
expect(parsed.search).toBe('?query=value');
|
|
20
|
+
expect(parsed.hash).toBe('#hash');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should parse simple URL', () => {
|
|
24
|
+
const parsed = url.parse('https://example.com');
|
|
25
|
+
|
|
26
|
+
expect(parsed.hostname).toBe('example.com');
|
|
27
|
+
expect(parsed.pathname).toBe('/');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should return null for invalid URL', () => {
|
|
31
|
+
expect(url.parse('not-a-url')).toBeNull();
|
|
32
|
+
expect(url.parse('')).toBeNull();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should handle query params', () => {
|
|
36
|
+
const parsed = url.parse('https://api.example.com/search?q=test&page=1');
|
|
37
|
+
|
|
38
|
+
expect(parsed.searchParams.get('q')).toBe('test');
|
|
39
|
+
expect(parsed.searchParams.get('page')).toBe('1');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should handle URLs with authentication', () => {
|
|
43
|
+
const parsed = url.parse('https://user:pass@example.com/path');
|
|
44
|
+
|
|
45
|
+
expect(parsed.username).toBe('user');
|
|
46
|
+
expect(parsed.password).toBe('pass');
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('SearchParams', () => {
|
|
51
|
+
it('should create URLSearchParams instance', () => {
|
|
52
|
+
const params = new url.SearchParams('foo=bar&baz=qux');
|
|
53
|
+
|
|
54
|
+
expect(params.get('foo')).toBe('bar');
|
|
55
|
+
expect(params.get('baz')).toBe('qux');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should serialize to string', () => {
|
|
59
|
+
const params = new url.SearchParams();
|
|
60
|
+
params.append('key', 'value');
|
|
61
|
+
params.append('another', 'test');
|
|
62
|
+
|
|
63
|
+
expect(params.toString()).toContain('key=value');
|
|
64
|
+
expect(params.toString()).toContain('another=test');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should handle encoded values', () => {
|
|
68
|
+
const params = new url.SearchParams();
|
|
69
|
+
params.set('message', 'Hello World!');
|
|
70
|
+
|
|
71
|
+
expect(params.toString()).toContain('Hello');
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should iterate over entries', () => {
|
|
75
|
+
const params = new url.SearchParams('a=1&b=2&c=3');
|
|
76
|
+
const entries = [...params.entries()];
|
|
77
|
+
|
|
78
|
+
expect(entries).toHaveLength(3);
|
|
79
|
+
expect(entries[0]).toEqual(['a', '1']);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
});
|
|
Binary file
|
|
@@ -31,8 +31,13 @@ export interface ShareContext {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
// Add more as needed based on native/index.js
|
|
34
|
+
export interface WebSocketModule {
|
|
35
|
+
send(socketId: string, message: string): void;
|
|
36
|
+
broadcast(message: string): void;
|
|
37
|
+
}
|
|
38
|
+
|
|
34
39
|
export const db: any;
|
|
35
|
-
export const ws:
|
|
40
|
+
export const ws: WebSocketModule;
|
|
36
41
|
export const path: any;
|
|
37
42
|
export const jwt: any;
|
|
38
43
|
export const password: any;
|
|
@@ -49,3 +54,13 @@ export const time: any;
|
|
|
49
54
|
export const url: any;
|
|
50
55
|
export const response: any;
|
|
51
56
|
export const valid: any;
|
|
57
|
+
|
|
58
|
+
// Serialization
|
|
59
|
+
/** Binary-serializes a JavaScript value using V8's fast internal format. */
|
|
60
|
+
export function serialize(value: any): Uint8Array;
|
|
61
|
+
/** Binary-serializes a JavaScript value using V8's fast internal format. Alias for serialize. */
|
|
62
|
+
export function serialise(value: any): Uint8Array;
|
|
63
|
+
/** Deserializes a Uint8Array back into its original JavaScript value/object. */
|
|
64
|
+
export function deserialize(buffer: Uint8Array): any;
|
|
65
|
+
/** Deserializes a Uint8Array back into its original JavaScript value/object. Alias for deserialize. */
|
|
66
|
+
export function deserialise(buffer: Uint8Array): any;
|
package/packages/native/index.js
CHANGED
|
@@ -40,4 +40,10 @@ export const url = t.url;
|
|
|
40
40
|
export const response = t.response;
|
|
41
41
|
export const valid = t.valid;
|
|
42
42
|
|
|
43
|
+
// Serialization
|
|
44
|
+
export const serialize = t.serialize;
|
|
45
|
+
export const serialise = t.serialise;
|
|
46
|
+
export const deserialize = t.deserialize;
|
|
47
|
+
export const deserialise = t.deserialise;
|
|
48
|
+
|
|
43
49
|
export const defineAction = (handler) => handler;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@titanpl/native",
|
|
3
|
-
"version": "7.0.0
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"description": "Titan native utilities package",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@titanpl/core": "
|
|
23
|
+
"@titanpl/core": "7.0.0",
|
|
24
24
|
"@titanpl/node": "latest"
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -233,6 +233,34 @@ export const password: typeof t.password;
|
|
|
233
233
|
*/
|
|
234
234
|
export const db: typeof t.db;
|
|
235
235
|
|
|
236
|
+
/**
|
|
237
|
+
* WebSocket communication utilities.
|
|
238
|
+
*
|
|
239
|
+
* Re-exported from the `t` global for module-style imports.
|
|
240
|
+
* @see {@link TitanRuntimeUtils.ws} for full documentation.
|
|
241
|
+
*/
|
|
242
|
+
export const ws: typeof t.ws;
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Binary serialization using V8's fast format.
|
|
246
|
+
*
|
|
247
|
+
* Re-exported from the `t` global for module-style imports.
|
|
248
|
+
* @see {@link TitanRuntimeUtils.serialize}
|
|
249
|
+
*/
|
|
250
|
+
export const serialize: typeof t.serialize;
|
|
251
|
+
/** Alias for serialize. @see {@link TitanRuntimeUtils.serialise} */
|
|
252
|
+
export const serialise: typeof t.serialise;
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Binary deserialization for V8 buffers.
|
|
256
|
+
*
|
|
257
|
+
* Re-exported from the `t` global for module-style imports.
|
|
258
|
+
* @see {@link TitanRuntimeUtils.deserialize}
|
|
259
|
+
*/
|
|
260
|
+
export const deserialize: typeof t.deserialize;
|
|
261
|
+
/** Alias for deserialize. @see {@link TitanRuntimeUtils.deserialise} */
|
|
262
|
+
export const deserialise: typeof t.deserialise;
|
|
263
|
+
|
|
236
264
|
/**
|
|
237
265
|
* Async file system operations (read, write, mkdir, stat, etc.).
|
|
238
266
|
*
|
|
@@ -647,6 +675,55 @@ declare global {
|
|
|
647
675
|
body?: string;
|
|
648
676
|
error?: string;
|
|
649
677
|
}>;
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Fast binary serialization using V8's internal value format.
|
|
681
|
+
*
|
|
682
|
+
* Highly efficient for complex JavaScript objects including `Date`, `Map`,
|
|
683
|
+
* `Set`, and `TypedArrays`. The resulting `Uint8Array` is stable and
|
|
684
|
+
* can be safely stored in databases (e.g. `t.ls`) or transmitted.
|
|
685
|
+
*
|
|
686
|
+
* @param value - The JavaScript value/object to serialize.
|
|
687
|
+
* @returns A `Uint8Array` containing the binary-serialized representation.
|
|
688
|
+
*
|
|
689
|
+
* @example
|
|
690
|
+
* ```js
|
|
691
|
+
* const complex = { date: new Date(), map: new Map([["a", 1]]) };
|
|
692
|
+
* const bytes = t.serialize(complex);
|
|
693
|
+
* // Store bytes in database or pass to another action
|
|
694
|
+
* ```
|
|
695
|
+
*/
|
|
696
|
+
serialize(value: any): Uint8Array;
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* Binary serialization. Alias for `t.serialize`.
|
|
700
|
+
* @see {@link TitanRuntimeUtils.serialize}
|
|
701
|
+
*/
|
|
702
|
+
serialise(value: any): Uint8Array;
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* Deserializes a binary buffer back into its original JavaScript value.
|
|
706
|
+
*
|
|
707
|
+
* Restores full object fidelity including native types like `Date` and `Buffer`.
|
|
708
|
+
* Performance is significantly faster than `JSON.parse` for large objects.
|
|
709
|
+
*
|
|
710
|
+
* @param buffer - A `Uint8Array` created by `t.serialize()`.
|
|
711
|
+
* @returns The restored JavaScript value or object.
|
|
712
|
+
* @throws If the buffer is invalid or contains corrupted V8 header data.
|
|
713
|
+
*
|
|
714
|
+
* @example
|
|
715
|
+
* ```js
|
|
716
|
+
* const restored = t.deserialize(bytes);
|
|
717
|
+
* console.log(restored.date instanceof Date); // true
|
|
718
|
+
* ```
|
|
719
|
+
*/
|
|
720
|
+
deserialize(buffer: Uint8Array): any;
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* Binary deserialization. Alias for `t.deserialize`.
|
|
724
|
+
* @see {@link TitanRuntimeUtils.deserialize}
|
|
725
|
+
*/
|
|
726
|
+
deserialise(buffer: Uint8Array): any;
|
|
650
727
|
|
|
651
728
|
/**
|
|
652
729
|
* WebSocket communication utilities.
|