From 3c4d05abd4f4bf61f9fe659f29e9a8a7ee7651b4 Mon Sep 17 00:00:00 2001 From: TopchetoEU <36534413+TopchetoEU@users.noreply.github.com> Date: Fri, 24 Jan 2025 22:37:52 +0200 Subject: [PATCH] restructuring of stdlibs --- lib/package.json | 1 + lib/rollup.config.js | 5 +- lib/src/lib/async.d.ts | 13 ++ lib/src/lib/iterator.d.ts | 6 +- .../polyfills/classPrivateFieldLooseBase.js | 3 + .../polyfills/classPrivateFieldLooseKey.js | 13 ++ lib/src/polyfills/createClass.js | 5 +- lib/src/stdlib/arrays/ArrayBuffer.ts | 23 ++- lib/src/stdlib/arrays/Int32Array.ts | 4 +- lib/src/stdlib/arrays/TypedArray.ts | 12 +- lib/src/stdlib/arrays/Uint8Array.ts | 4 +- lib/src/stdlib/classes/date.ts | 8 +- lib/src/stdlib/classes/map.ts | 51 +++-- lib/src/stdlib/classes/promise.ts | 193 +++++++++--------- lib/src/stdlib/classes/set.ts | 43 ++-- lib/src/stdlib/primordials.ts | 16 +- lib/src/stdlib/sockets.ts | 63 ++++++ lib/src/stdlib/values/regex.ts | 17 +- 18 files changed, 293 insertions(+), 187 deletions(-) create mode 100644 lib/src/polyfills/classPrivateFieldLooseBase.js create mode 100644 lib/src/polyfills/classPrivateFieldLooseKey.js create mode 100644 lib/src/stdlib/sockets.ts diff --git a/lib/package.json b/lib/package.json index 8a8546f..21615be 100644 --- a/lib/package.json +++ b/lib/package.json @@ -17,6 +17,7 @@ "typescript": "^5.7.2" }, "devDependencies": { + "@babel/plugin-proposal-class-properties": "^7.18.6", "@babel/plugin-transform-class-properties": "^7.25.9", "@babel/plugin-transform-runtime": "^7.25.9", "@babel/plugin-transform-typescript": "^7.25.9", diff --git a/lib/rollup.config.js b/lib/rollup.config.js index 9d95808..5494f62 100644 --- a/lib/rollup.config.js +++ b/lib/rollup.config.js @@ -34,7 +34,6 @@ const construct = (input, output) => defineConfig({ optimizeConstEnums: true, allowDeclareFields: true, }], - ["@babel/plugin-transform-class-properties"], ["@babel/plugin-transform-runtime", { moduleName: shouldPolyfill() ? "!polyfills:" : undefined, version: "^7.24.0", @@ -48,6 +47,7 @@ const construct = (input, output) => defineConfig({ assumptions: { ignoreToPrimitiveHint: true, noClassCalls: true, + privateFieldsAsProperties: true, }, env: { @@ -77,7 +77,8 @@ const construct = (input, output) => defineConfig({ "@babel/plugin-transform-optional-chaining", "@babel/plugin-transform-logical-assignment-operators", "@babel/plugin-transform-numeric-separator", - "@babel/plugin-transform-class-properties", + "@babel/plugin-transform-private-methods", + "@babel/plugin-proposal-class-properties", "@babel/plugin-transform-class-static-block", "@babel/plugin-transform-regenerator", diff --git a/lib/src/lib/async.d.ts b/lib/src/lib/async.d.ts index 1e57b4d..7929c09 100644 --- a/lib/src/lib/async.d.ts +++ b/lib/src/lib/async.d.ts @@ -22,3 +22,16 @@ declare interface PromiseConstructor { resolve(val: T): Promise>; reject(err: unknown): Promise; } + +declare interface AsyncIterator { + next(): Promise>; + next(val: Next): Promise>; + error?(err: unknown): Promise>; + return?(val: Return): Promise>; +} +declare interface AsyncIterableIterator extends AsyncIterator { + [Symbol.iterator](): this; +} +declare interface AsyncIterable { + [Symbol.iterator](): AsyncIterator; +} diff --git a/lib/src/lib/iterator.d.ts b/lib/src/lib/iterator.d.ts index 18749db..2dfd0b1 100644 --- a/lib/src/lib/iterator.d.ts +++ b/lib/src/lib/iterator.d.ts @@ -1,12 +1,12 @@ declare interface NormalIterationData { value: T; - done: true; + done: false; } declare interface DoneIterationData { value: T; - done?: false; + done?: true; } -declare type IterationData = NormalIterationData | DoneIterationData; +declare type IterationData = NormalIterationData | DoneIterationData; declare interface Iterator { next(): IterationData; diff --git a/lib/src/polyfills/classPrivateFieldLooseBase.js b/lib/src/polyfills/classPrivateFieldLooseBase.js new file mode 100644 index 0000000..df8045c --- /dev/null +++ b/lib/src/polyfills/classPrivateFieldLooseBase.js @@ -0,0 +1,3 @@ +export default function _classPrivateFieldLooseBase(obj) { + return obj; +} \ No newline at end of file diff --git a/lib/src/polyfills/classPrivateFieldLooseKey.js b/lib/src/polyfills/classPrivateFieldLooseKey.js new file mode 100644 index 0000000..ab1c35a --- /dev/null +++ b/lib/src/polyfills/classPrivateFieldLooseKey.js @@ -0,0 +1,13 @@ +import { print, self, symbol } from "../stdlib/primordials.ts"; +import { Object } from "../stdlib/values/object.ts"; + +self.Object = { + defineProperty: function (obj, key, desc) { + if (obj == null) return obj; + Object.defineProperty(obj, key, desc); + } +}; + +export default function _classPrivateFieldLooseKey(key) { + return symbol.makeSymbol(key); +} \ No newline at end of file diff --git a/lib/src/polyfills/createClass.js b/lib/src/polyfills/createClass.js index 1da41a7..2e2b2bb 100644 --- a/lib/src/polyfills/createClass.js +++ b/lib/src/polyfills/createClass.js @@ -1,4 +1,4 @@ -import { object } from "../stdlib/primordials.ts"; +import { func, object, print } from "../stdlib/primordials.ts"; function _defineProperties(target, arr) { if (!arr) return; @@ -31,5 +31,8 @@ export default function _createClass(clazz, instance, nonInstance) { _defineProperties(clazz.prototype, instance); _defineProperties(clazz, nonInstance); + func.setCallable(clazz, false); + func.setConstructable(clazz, true); + return clazz; } \ No newline at end of file diff --git a/lib/src/stdlib/arrays/ArrayBuffer.ts b/lib/src/stdlib/arrays/ArrayBuffer.ts index 0474256..20e49a2 100644 --- a/lib/src/stdlib/arrays/ArrayBuffer.ts +++ b/lib/src/stdlib/arrays/ArrayBuffer.ts @@ -1,25 +1,28 @@ import { buffer, type InternalBuffer, map, symbol } from "../primordials.ts"; export const abs = new map(true); -export const abKey: unique symbol = symbol.getSymbol("ArrayBuffer.impl") as any; export class ArrayBuffer { - public [abKey]!: InternalBuffer; + #internal!: InternalBuffer; public get byteLength() { - return this[abKey].length; + return this.#internal.length; } public get byteOffset() { return 0; } public constructor(val: unknown) { - if (buffer.isBuff(val)) this[abKey] = val; - else this[abKey] = buffer.buff(Number(val)); + if (buffer.isBuff(val)) this.#internal = val; + else this.#internal = buffer.buff(Number(val)); + } + + public static unwrap(instance: ArrayBuffer) { + return instance.#internal; } } -export function getAB(buff: InternalBuffer): ArrayBuffer { +function wrapAB(buff: InternalBuffer): ArrayBuffer { let res = abs.get(buff); if (res == null) { res = new ArrayBuffer(buff); @@ -28,3 +31,11 @@ export function getAB(buff: InternalBuffer): ArrayBuffer { return res; } +const unwrapAB = ArrayBuffer.unwrap; + +delete (ArrayBuffer as any).unwrap; + + + +export { wrapAB, unwrapAB }; + diff --git a/lib/src/stdlib/arrays/Int32Array.ts b/lib/src/stdlib/arrays/Int32Array.ts index a99f165..37409a5 100644 --- a/lib/src/stdlib/arrays/Int32Array.ts +++ b/lib/src/stdlib/arrays/Int32Array.ts @@ -1,5 +1,5 @@ import { buffer } from "../primordials.ts"; -import { abstractIgnore, TypedArray, typedArrayFuncs } from "./TypedArray.ts"; +import { token, TypedArray, typedArrayFuncs } from "./TypedArray.ts"; const factory = buffer.int32; const funcs = typedArrayFuncs(4, factory); @@ -19,7 +19,7 @@ export class Int32Array extends TypedArray { } public constructor(obj: any, start?: number, end?: number) { - super(abstractIgnore); + super(token); return funcs.construct(obj, start, end) as any; } } \ No newline at end of file diff --git a/lib/src/stdlib/arrays/TypedArray.ts b/lib/src/stdlib/arrays/TypedArray.ts index 44cc853..b373167 100644 --- a/lib/src/stdlib/arrays/TypedArray.ts +++ b/lib/src/stdlib/arrays/TypedArray.ts @@ -1,9 +1,9 @@ import { buffer, func, type InternalBuffer, object, string, symbol } from "../primordials.ts"; import { symbols, wrapI } from "../utils.ts"; import { Error, TypeError } from "../values/errors.ts"; -import { abKey, ArrayBuffer, getAB } from "./ArrayBuffer.ts"; +import { ArrayBuffer, unwrapAB, wrapAB } from "./ArrayBuffer.ts"; -export const abstractIgnore = symbol.getSymbol("TypedArray.abstractIgnore"); +export const token = symbol.getSymbol("TypedArray.abstractIgnore"); export function typedArrayFuncs(perEl: number, constructor: (buff: InternalBuffer, start: number, end: number) => number[]) { return { @@ -56,7 +56,7 @@ export function typedArrayFuncs(perEl: number, constructor: (buff: InternalBuffe return constructor(buffer.buff(self * perEl), 0, self); } if (self instanceof ArrayBuffer) { - const internal = self[abKey]; + const internal = unwrapAB(self); if (start === undefined) start = 0; if (end === undefined) end = (internal.length / perEl) | 0; return constructor(internal, start, end); @@ -90,7 +90,7 @@ export function typedArrayFuncs(perEl: number, constructor: (buff: InternalBuffe export class TypedArray { public get buffer() { - return getAB(buffer.backer(this as any)); + return wrapAB(buffer.backer(this as any)); } public get byteOffset(): number { throw new Error("abstract"); @@ -212,8 +212,8 @@ export class TypedArray { return this; } - public constructor(token?: typeof abstractIgnore) { - if (token !== abstractIgnore) { + public constructor(_token?: typeof token) { + if (_token !== token) { throw new TypeError("TypedArray constructor can't be called"); } } diff --git a/lib/src/stdlib/arrays/Uint8Array.ts b/lib/src/stdlib/arrays/Uint8Array.ts index c40bf2e..8b7bafc 100644 --- a/lib/src/stdlib/arrays/Uint8Array.ts +++ b/lib/src/stdlib/arrays/Uint8Array.ts @@ -1,5 +1,5 @@ import { buffer } from "../primordials.ts"; -import { abstractIgnore, TypedArray, typedArrayFuncs } from "./TypedArray.ts"; +import { token, TypedArray, typedArrayFuncs } from "./TypedArray.ts"; const factory = buffer.uint8; const funcs = typedArrayFuncs(1, factory); @@ -26,7 +26,7 @@ export class Uint8Array extends TypedArray { } public constructor(obj: any, start?: number, end?: number) { - super(abstractIgnore); + super(token); return funcs.construct(obj, start, end) as any; } } \ No newline at end of file diff --git a/lib/src/stdlib/classes/date.ts b/lib/src/stdlib/classes/date.ts index e2f2f19..26944a5 100644 --- a/lib/src/stdlib/classes/date.ts +++ b/lib/src/stdlib/classes/date.ts @@ -1,13 +1,11 @@ -import { now, symbol } from "../primordials.ts"; - -const timeKey: unique symbol = symbol.makeSymbol("") as any; +import { now, number, symbol } from "../primordials.ts"; export const Date = (() => { class Date { - [timeKey]!: number; + #time: number; public constructor() { - + this.#time = number.NaN; } public static now() { diff --git a/lib/src/stdlib/classes/map.ts b/lib/src/stdlib/classes/map.ts index 5fa5ea2..17b07ed 100644 --- a/lib/src/stdlib/classes/map.ts +++ b/lib/src/stdlib/classes/map.ts @@ -1,51 +1,49 @@ import { Array } from "../values/array.ts"; -import { func, map, symbol } from "../primordials.ts"; +import { func, map } from "../primordials.ts"; import { symbols } from "../utils.ts"; -const mapKey: unique symbol = symbol.makeSymbol("Map.impl") as any; - export class Map { - private [mapKey]: InstanceType; + #map: InstanceType; public get size() { - return this[mapKey].size(); + return this.#map.size(); } public get(key: K): V { - return this[mapKey].get(key); + return this.#map.get(key); } public has(key: K): boolean { - return this[mapKey].has(key); + return this.#map.has(key); } public set(key: K, val: V) { - this[mapKey].set(key, val); + this.#map.set(key, val); return this; } public delete(key: K): boolean { - if (!this[mapKey].has(key)) return false; + if (!this.#map.has(key)) return false; else { - this[mapKey].delete(key); + this.#map.delete(key); return true; } } public clear() { - this[mapKey].clear(); + this.#map.clear(); } public keys(): K[] { - return this[mapKey].keys(); + return this.#map.keys(); } public values(): V[] { - const res = this[mapKey].keys(); + const res = this.#map.keys(); for (let i = 0; i < res.length; i++) { - res[i] = this[mapKey].get(res[i]); + res[i] = this.#map.get(res[i]); } return res; } public entries(): [K, V][] { - const res = this[mapKey].keys(); + const res = this.#map.keys(); for (let i = 0; i < res.length; i++) { - res[i] = [res[i], this[mapKey].get(res[i])]; + res[i] = [res[i], this.#map.get(res[i])]; } return res; } @@ -62,7 +60,7 @@ export class Map { } public constructor(iterable?: Iterable<[K, V]>) { - const _map = this[mapKey] = new map(); + const _map = this.#map = new map(); if (iterable != null) { if (Array.isArray(iterable)) { @@ -81,31 +79,31 @@ export class Map { } } export class WeakMap { - private [mapKey]: InstanceType; + #map: InstanceType; public get(key: K): V { - return this[mapKey].get(key); + return this.#map.get(key); } public has(key: K): boolean { - return this[mapKey].has(key); + return this.#map.has(key); } public set(key: K, val: V) { - this[mapKey].set(key, val); + this.#map.set(key, val); return this; } public delete(key: K): boolean { - if (!this[mapKey].has(key)) return false; + if (!this.#map.has(key)) return false; else { - this[mapKey].delete(key); + this.#map.delete(key); return true; } } public clear() { - this[mapKey].clear(); + this.#map.clear(); } public constructor(iterable?: Iterable<[K, V]>) { - const _map = this[mapKey] = new map(true); + const _map = this.#map = new map(true); if (iterable != null) { if (Array.isArray(iterable)) { @@ -123,6 +121,3 @@ export class WeakMap { } } } - -func.setCallable(Map, false); -func.setCallable(WeakMap, false); diff --git a/lib/src/stdlib/classes/promise.ts b/lib/src/stdlib/classes/promise.ts index 64e8140..6dddbe2 100644 --- a/lib/src/stdlib/classes/promise.ts +++ b/lib/src/stdlib/classes/promise.ts @@ -1,4 +1,4 @@ -import { func, next, object, symbol } from "../primordials.ts"; +import { next } from "../primordials.ts"; enum PromiseState { Pending = "pend", @@ -6,109 +6,106 @@ enum PromiseState { Rejected = "rej", } -const pState: unique symbol = symbol.makeSymbol("Promise.state") as any; -const pValue: unique symbol = symbol.makeSymbol("Promise.value") as any; -const pFulHandles: unique symbol = symbol.makeSymbol("Promise.fulfillHandles") as any; -const pRejHandles: unique symbol = symbol.makeSymbol("Promise.rejectHandles") as any; - -function makePromise(): Promise { - return object.setPrototype({ - [pState]: PromiseState.Pending, - [pFulHandles]: [], - [pRejHandles]: [], - }, Promise.prototype) as Promise; -} - -function fulfill(self: Promise, val: any) { - if (self[pState] !== PromiseState.Pending) return; - if (self === val) throw new Error("A promise may not be fulfilled with itself"); - - if (val != null && typeof val.then === "function") { - val.then( - (val: any) => fulfill(self, val), - (err: any) => reject(self, err), - ); - } - else { - self[pValue] = val; - self[pState] = PromiseState.Fulfilled; - - const handles = self[pFulHandles]!; - - for (let i = 0; i < handles.length; i++) { - handles[i](val); - } - - self[pFulHandles] = undefined; - self[pRejHandles] = undefined; - } -} -function reject(self: Promise, val: any) { - if (self[pState] !== PromiseState.Pending) return; - if (self === val) throw new Error("A promise may not be rejected with itself"); - - if (val != null && typeof val.then === "function") { - val.then( - (val: any) => reject(self, val), - (err: any) => reject(self, err), - ); - } - else { - self[pValue] = val; - self[pState] = PromiseState.Rejected; - - const handles = self[pRejHandles]!; - - for (let i = 0; i < handles.length; i++) { - handles[i](val); - } - - self[pFulHandles] = undefined; - self[pRejHandles] = undefined; - } -} -function handle(self: Promise, ful?: (val: T) => void, rej?: (err: any) => void) { - if (self[pState] === PromiseState.Pending) { - if (ful != null) { - self[pFulHandles]![self[pFulHandles]!.length] = ful; - } - if (rej != null) { - self[pRejHandles]![self[pRejHandles]!.length] = rej; - } - } - else if (self[pState] === PromiseState.Fulfilled) { - if (ful != null) ful(self[pValue] as T); - } - else if (self[pState] === PromiseState.Rejected) { - if (rej != null) rej(self[pValue]); - } -} - export class Promise { - public [pState]: PromiseState; - public [pValue]?: T | unknown; - public [pFulHandles]?: ((val: T) => void)[] = []; - public [pRejHandles]?: ((val: T) => void)[] = []; + static #InternalPromise = function (this: Promise) { + this.#state = PromiseState.Pending; + this.#fulHandles = []; + this.#rejHandles = []; + } as any as new () => Promise; + + static { + this.#InternalPromise.prototype = this.prototype; + } + + #state: PromiseState; + #value?: T | unknown; + #fulHandles?: ((val: T) => void)[] = []; + #rejHandles?: ((val: T) => void)[] = []; + + #fulfill(val: any) { + if (this.#state !== PromiseState.Pending) return; + if (this === val) throw new Error("A promise may not be fulfilled with itself"); + + if (val != null && typeof val.then === "function") { + val.then( + (val: any) => this.#fulfill(val), + (err: any) => this.#reject(err), + ); + } + else { + this.#value = val; + this.#state = PromiseState.Fulfilled; + + const handles = this.#fulHandles!; + + for (let i = 0; i < handles.length; i++) { + handles[i](val); + } + + this.#fulHandles = undefined; + this.#rejHandles = undefined; + } + } + #reject(val: any) { + if (this.#state !== PromiseState.Pending) return; + if (this === val) throw new Error("A promise may not be rejected with itself"); + + if (val != null && typeof val.then === "function") { + val.then( + (val: any) => this.#reject(val), + (err: any) => this.#reject(err), + ); + } + else { + this.#value = val; + this.#state = PromiseState.Rejected; + + const handles = this.#rejHandles!; + + for (let i = 0; i < handles.length; i++) { + handles[i](val); + } + + this.#fulHandles = undefined; + this.#rejHandles = undefined; + } + } + #handle(ful?: (val: T) => void, rej?: (err: any) => void) { + if (this.#state === PromiseState.Pending) { + if (ful != null) { + this.#fulHandles![this.#fulHandles!.length] = ful; + } + if (rej != null) { + this.#rejHandles![this.#rejHandles!.length] = rej; + } + } + else if (this.#state === PromiseState.Fulfilled) { + if (ful != null) ful(this.#value as T); + } + else if (this.#state === PromiseState.Rejected) { + if (rej != null) rej(this.#value); + } + } public then(ful?: (val: T) => Res, rej?: (err: any) => Res) { if (typeof ful !== "function") ful = undefined; if (typeof rej !== "function") rej = undefined; - const promise = makePromise(); + const promise = new Promise.#InternalPromise(); - handle(this, + this.#handle( val => next(() => { - if (ful == null) fulfill(promise, val); + if (ful == null) promise.#fulfill(val); else { - try { fulfill(promise, ful(val)); } - catch (e) { reject(promise, e); } + try { promise.#fulfill(ful(val)); } + catch (e) { promise.#reject(e); } } }), err => next(() => { - if (rej == null) reject(promise, err); + if (rej == null) promise.#reject(err); else { - try { fulfill(promise, rej(err)); } - catch (e) { reject(promise, e); } + try { promise.#fulfill(rej(err)); } + catch (e) { promise.#reject(e); } } }), ); @@ -134,21 +131,19 @@ export class Promise { } public constructor(fn: (fulfil: (val: T) => void, reject: (err: unknown) => void) => void) { - this[pState] = PromiseState.Pending; + this.#state = PromiseState.Pending; - fn(val => fulfill(this, val), err => reject(this, err)); + fn(val => this.#fulfill(val), err => this.#reject(err)); } public static resolve(val: any) { - const res = makePromise(); - fulfill(res, val); + const res = new this.#InternalPromise(); + res.#fulfill(val); return res; } public static reject(val: any) { - const res = makePromise(); - reject(res, val); + const res = new this.#InternalPromise(); + res.#reject(val); return res; } } - -func.setCallable(Promise, false); diff --git a/lib/src/stdlib/classes/set.ts b/lib/src/stdlib/classes/set.ts index 8971b93..95c3e44 100644 --- a/lib/src/stdlib/classes/set.ts +++ b/lib/src/stdlib/classes/set.ts @@ -1,42 +1,40 @@ import { Array } from "../values/array.ts"; -import { func, map, symbol } from "../primordials.ts"; +import { func, map } from "../primordials.ts"; import { symbols } from "../utils.ts"; -const mapKey: unique symbol = symbol.makeSymbol("Set.impl") as any; - export class Set { - private [mapKey]: InstanceType; + #map: InstanceType; public get size() { - return this[mapKey].size(); + return this.#map.size(); } public has(key: T): boolean { - return this[mapKey].has(key); + return this.#map.has(key); } public add(val: T) { - this[mapKey].set(val, true); + this.#map.set(val, true); return this; } public delete(val: T): boolean { - if (!this[mapKey].has(val)) return false; + if (!this.#map.has(val)) return false; else { - this[mapKey].delete(val); + this.#map.delete(val); return true; } } public clear() { - this[mapKey].clear(); + this.#map.clear(); } public keys(): T[] { - return this[mapKey].keys(); + return this.#map.keys(); } public values(): T[] { - return this[mapKey].keys(); + return this.#map.keys(); } public entries(): [T, T][] { - const res = this[mapKey].keys(); + const res = this.#map.keys(); for (let i = 0; i < res.length; i++) { res[i] = [res[i], res[i]]; @@ -57,7 +55,7 @@ export class Set { } public constructor(iterable?: Iterable) { - const _map = this[mapKey] = new map(); + const _map = this.#map = new map(); if (iterable != null) { if (Array.isArray(iterable)) { @@ -77,28 +75,28 @@ export class Set { } export class WeakSet { - private [mapKey]: InstanceType; + #map: InstanceType; public has(key: T): boolean { - return this[mapKey].has(key); + return this.#map.has(key); } public add(val: T) { - this[mapKey].set(val, true); + this.#map.set(val, true); return this; } public delete(val: T): boolean { - if (!this[mapKey].has(val)) return false; + if (!this.#map.has(val)) return false; else { - this[mapKey].delete(val); + this.#map.delete(val); return true; } } public clear() { - this[mapKey].clear(); + this.#map.clear(); } public constructor(iterable?: Iterable) { - const _map = this[mapKey] = new map(true); + const _map = this.#map = new map(true); if (iterable != null) { if (Array.isArray(iterable)) { @@ -116,6 +114,3 @@ export class WeakSet { } } } - -func.setCallable(Set, false); -func.setCallable(WeakSet, false); diff --git a/lib/src/stdlib/primordials.ts b/lib/src/stdlib/primordials.ts index 0cd54a2..3fe8e35 100644 --- a/lib/src/stdlib/primordials.ts +++ b/lib/src/stdlib/primordials.ts @@ -4,6 +4,14 @@ export interface InternalBuffer { length: number; [buffSymbol]: "buffer"; } +export interface InternalSocket { + read(onRes: (data: Uint8Array) => void, onErr: (err: unknown) => void, onDone: () => void): void; + write(data: Uint8Array, onRes: () => void, onErr: (err: unknown) => void): void; +} +export interface InternalServer { + bind(address: string, onRes: () => void, onErr: (err: unknown) => void): void; + next(onRes: (socket: InternalSocket) => void, onErr: (err: unknown) => void, onDone: () => void): void; +} export interface SymbolPrimordials { makeSymbol(name: string): symbol; @@ -82,6 +90,9 @@ export interface JSONPrimordials { parse(data: string): any; stringify(data: any): string; } +export interface NetPrimordials { + server(): InternalServer; +} export interface Primordials { symbol: SymbolPrimordials; @@ -91,6 +102,7 @@ export interface Primordials { function: FunctionPrimordials; json: JSONPrimordials; buffer: BufferPrimordials; + net: NetPrimordials; map: new (weak?: boolean) => { get(key: any): any; has(key: any): boolean; @@ -127,6 +139,7 @@ export const { buffer, function: func, json, + net: socket, map, regex, setGlobalPrototypes, @@ -138,4 +151,5 @@ export const { print, } = primordials; -export type regex = InstanceType; \ No newline at end of file +export type regex = InstanceType; +export const self = (globalThis as any); diff --git a/lib/src/stdlib/sockets.ts b/lib/src/stdlib/sockets.ts new file mode 100644 index 0000000..8ccfe0d --- /dev/null +++ b/lib/src/stdlib/sockets.ts @@ -0,0 +1,63 @@ +import { Promise as Promise } from "./classes/promise"; +import { func, InternalServer, InternalSocket, symbol } from "./primordials"; +import { Error } from "./values/errors"; + +const socketToken = symbol.makeSymbol("ServerSocket.token"); + +export class ServerSocket { + #internal: InternalSocket; + + public read() { + return new Promise((ful, rej) => { + this.#internal.read(ful, rej, ful as any); + }); + } + public write(data: Uint8Array) { + return new Promise((ful, rej) => { + this.#internal.write(data, ful, rej); + }); + } + + public next() { + return new Promise((ful, rej) => { + this.#internal.read( + data => ful({ value: data, done: false }), + rej, + () => ful({ value: undefined, done: true }) + ); + }); + } + public [Symbol.iterator](): this { + return this; + } + + public constructor(token: typeof socketToken, socket: InternalSocket) { + if (token !== socketToken) throw new Error("Invalid token for creation"); + this.#internal = socket; + } +} + +export class Server { + #internal: InternalServer; + + public bind(address: string) { + return new Promise((res, rej) => this.#internal.bind(address, res, rej)); + } + + public next() { + return new Promise((ful, rej) => { + this.#internal.next( + data => ful({ value: new ServerSocket(socketToken, data), done: false }), + rej, + () => ful({ value: undefined, done: true }) + ); + }); + } + public [Symbol.iterator](): this { + return this; + } + + public constructor(server: InternalServer) { + this.#internal = server; + } +} diff --git a/lib/src/stdlib/values/regex.ts b/lib/src/stdlib/values/regex.ts index 41b9d0f..df49dab 100644 --- a/lib/src/stdlib/values/regex.ts +++ b/lib/src/stdlib/values/regex.ts @@ -1,14 +1,12 @@ -import { func, regex, symbol } from "../primordials.ts"; +import { func, regex } from "../primordials.ts"; import { String } from "./string.ts"; import { type ReplaceRange } from "../utils.ts"; import { applyReplaces } from "../utils.ts"; import { applySplits } from "../utils.ts"; import { symbols } from "../utils.ts"; -const regexKey: unique symbol = symbol.makeSymbol("RegExp.impl") as any; - export class RegExp { - private [regexKey]!: InstanceType; + #regex!: InstanceType; public readonly source!: string; public readonly flags!: string; @@ -70,14 +68,14 @@ export class RegExp { this.unicodeSets = unicodeSets; this.sticky = sticky; - this[regexKey] = new regex(source, multiline, ignoreCase, dotall, unicode, unicodeSets); + this.#regex = new regex(source, multiline, ignoreCase, dotall, unicode, unicodeSets); } public exec(target: string) { const useLast = this.global || this.sticky; const start = useLast ? this.lastIndex : 0; - const match = this[regexKey].exec(target, start, this.indices); + const match = this.#regex.exec(target, start, this.indices); if (match != null && !(this.sticky && match.matches.index !== start)) { if (useLast) this.lastIndex = match.end; return match.matches; @@ -92,7 +90,7 @@ export class RegExp { public [symbols.split](target: string, limit?: number) { return applySplits(target, limit, offset => { - const val = this[regexKey].exec(target, offset, false); + const val = this.#regex.exec(target, offset, false); if (val == null) return undefined; return { start: val.matches.index!, end: val.end }; @@ -100,7 +98,7 @@ export class RegExp { } public [symbols.replace](target: string, replacer: any) { const matches: ReplaceRange[] = []; - const regex = this[regexKey]; + const regex = this.#regex; if (this.global) { let offset = 0; @@ -136,3 +134,6 @@ export class RegExp { return applyReplaces(target, matches, replacer, regex.groupCount() + 1); } } + +func.setCallable(RegExp, true); +func.setConstructable(RegExp, true);