restructuring of stdlibs
This commit is contained in:
parent
f16d088646
commit
3c4d05abd4
@ -17,6 +17,7 @@
|
|||||||
"typescript": "^5.7.2"
|
"typescript": "^5.7.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
||||||
"@babel/plugin-transform-class-properties": "^7.25.9",
|
"@babel/plugin-transform-class-properties": "^7.25.9",
|
||||||
"@babel/plugin-transform-runtime": "^7.25.9",
|
"@babel/plugin-transform-runtime": "^7.25.9",
|
||||||
"@babel/plugin-transform-typescript": "^7.25.9",
|
"@babel/plugin-transform-typescript": "^7.25.9",
|
||||||
|
@ -34,7 +34,6 @@ const construct = (input, output) => defineConfig({
|
|||||||
optimizeConstEnums: true,
|
optimizeConstEnums: true,
|
||||||
allowDeclareFields: true,
|
allowDeclareFields: true,
|
||||||
}],
|
}],
|
||||||
["@babel/plugin-transform-class-properties"],
|
|
||||||
["@babel/plugin-transform-runtime", {
|
["@babel/plugin-transform-runtime", {
|
||||||
moduleName: shouldPolyfill() ? "!polyfills:" : undefined,
|
moduleName: shouldPolyfill() ? "!polyfills:" : undefined,
|
||||||
version: "^7.24.0",
|
version: "^7.24.0",
|
||||||
@ -48,6 +47,7 @@ const construct = (input, output) => defineConfig({
|
|||||||
assumptions: {
|
assumptions: {
|
||||||
ignoreToPrimitiveHint: true,
|
ignoreToPrimitiveHint: true,
|
||||||
noClassCalls: true,
|
noClassCalls: true,
|
||||||
|
privateFieldsAsProperties: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
env: {
|
env: {
|
||||||
@ -77,7 +77,8 @@ const construct = (input, output) => defineConfig({
|
|||||||
"@babel/plugin-transform-optional-chaining",
|
"@babel/plugin-transform-optional-chaining",
|
||||||
"@babel/plugin-transform-logical-assignment-operators",
|
"@babel/plugin-transform-logical-assignment-operators",
|
||||||
"@babel/plugin-transform-numeric-separator",
|
"@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-class-static-block",
|
||||||
"@babel/plugin-transform-regenerator",
|
"@babel/plugin-transform-regenerator",
|
||||||
|
|
||||||
|
13
lib/src/lib/async.d.ts
vendored
13
lib/src/lib/async.d.ts
vendored
@ -22,3 +22,16 @@ declare interface PromiseConstructor {
|
|||||||
resolve<T>(val: T): Promise<Awaited<T>>;
|
resolve<T>(val: T): Promise<Awaited<T>>;
|
||||||
reject<T>(err: unknown): Promise<T>;
|
reject<T>(err: unknown): Promise<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare interface AsyncIterator<T, Return = unknown, Next = unknown> {
|
||||||
|
next(): Promise<IterationData<T, Return>>;
|
||||||
|
next(val: Next): Promise<IterationData<T, Return>>;
|
||||||
|
error?(err: unknown): Promise<IterationData<T, Return>>;
|
||||||
|
return?(val: Return): Promise<IterationData<T, Return>>;
|
||||||
|
}
|
||||||
|
declare interface AsyncIterableIterator<T, Return = unknown, Next = unknown> extends AsyncIterator<T, Return, Next> {
|
||||||
|
[Symbol.iterator](): this;
|
||||||
|
}
|
||||||
|
declare interface AsyncIterable<T> {
|
||||||
|
[Symbol.iterator](): AsyncIterator<T>;
|
||||||
|
}
|
||||||
|
6
lib/src/lib/iterator.d.ts
vendored
6
lib/src/lib/iterator.d.ts
vendored
@ -1,12 +1,12 @@
|
|||||||
declare interface NormalIterationData<T> {
|
declare interface NormalIterationData<T> {
|
||||||
value: T;
|
value: T;
|
||||||
done: true;
|
done: false;
|
||||||
}
|
}
|
||||||
declare interface DoneIterationData<T> {
|
declare interface DoneIterationData<T> {
|
||||||
value: T;
|
value: T;
|
||||||
done?: false;
|
done?: true;
|
||||||
}
|
}
|
||||||
declare type IterationData<T, Return> = NormalIterationData<T> | DoneIterationData<Return>;
|
declare type IterationData<T, Return = void> = NormalIterationData<T> | DoneIterationData<Return>;
|
||||||
|
|
||||||
declare interface Iterator<T, Return = unknown, Next = unknown> {
|
declare interface Iterator<T, Return = unknown, Next = unknown> {
|
||||||
next(): IterationData<T, Return>;
|
next(): IterationData<T, Return>;
|
||||||
|
3
lib/src/polyfills/classPrivateFieldLooseBase.js
Normal file
3
lib/src/polyfills/classPrivateFieldLooseBase.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default function _classPrivateFieldLooseBase(obj) {
|
||||||
|
return obj;
|
||||||
|
}
|
13
lib/src/polyfills/classPrivateFieldLooseKey.js
Normal file
13
lib/src/polyfills/classPrivateFieldLooseKey.js
Normal file
@ -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);
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { object } from "../stdlib/primordials.ts";
|
import { func, object, print } from "../stdlib/primordials.ts";
|
||||||
|
|
||||||
function _defineProperties(target, arr) {
|
function _defineProperties(target, arr) {
|
||||||
if (!arr) return;
|
if (!arr) return;
|
||||||
@ -31,5 +31,8 @@ export default function _createClass(clazz, instance, nonInstance) {
|
|||||||
_defineProperties(clazz.prototype, instance);
|
_defineProperties(clazz.prototype, instance);
|
||||||
_defineProperties(clazz, nonInstance);
|
_defineProperties(clazz, nonInstance);
|
||||||
|
|
||||||
|
func.setCallable(clazz, false);
|
||||||
|
func.setConstructable(clazz, true);
|
||||||
|
|
||||||
return clazz;
|
return clazz;
|
||||||
}
|
}
|
@ -1,25 +1,28 @@
|
|||||||
import { buffer, type InternalBuffer, map, symbol } from "../primordials.ts";
|
import { buffer, type InternalBuffer, map, symbol } from "../primordials.ts";
|
||||||
|
|
||||||
export const abs = new map(true);
|
export const abs = new map(true);
|
||||||
export const abKey: unique symbol = symbol.getSymbol("ArrayBuffer.impl") as any;
|
|
||||||
|
|
||||||
export class ArrayBuffer {
|
export class ArrayBuffer {
|
||||||
public [abKey]!: InternalBuffer;
|
#internal!: InternalBuffer;
|
||||||
|
|
||||||
public get byteLength() {
|
public get byteLength() {
|
||||||
return this[abKey].length;
|
return this.#internal.length;
|
||||||
}
|
}
|
||||||
public get byteOffset() {
|
public get byteOffset() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public constructor(val: unknown) {
|
public constructor(val: unknown) {
|
||||||
if (buffer.isBuff(val)) this[abKey] = val;
|
if (buffer.isBuff(val)) this.#internal = val;
|
||||||
else this[abKey] = buffer.buff(Number(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);
|
let res = abs.get(buff);
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
res = new ArrayBuffer(buff);
|
res = new ArrayBuffer(buff);
|
||||||
@ -28,3 +31,11 @@ export function getAB(buff: InternalBuffer): ArrayBuffer {
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
const unwrapAB = ArrayBuffer.unwrap;
|
||||||
|
|
||||||
|
delete (ArrayBuffer as any).unwrap;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export { wrapAB, unwrapAB };
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { buffer } from "../primordials.ts";
|
import { buffer } from "../primordials.ts";
|
||||||
import { abstractIgnore, TypedArray, typedArrayFuncs } from "./TypedArray.ts";
|
import { token, TypedArray, typedArrayFuncs } from "./TypedArray.ts";
|
||||||
|
|
||||||
const factory = buffer.int32;
|
const factory = buffer.int32;
|
||||||
const funcs = typedArrayFuncs(4, factory);
|
const funcs = typedArrayFuncs(4, factory);
|
||||||
@ -19,7 +19,7 @@ export class Int32Array extends TypedArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public constructor(obj: any, start?: number, end?: number) {
|
public constructor(obj: any, start?: number, end?: number) {
|
||||||
super(abstractIgnore);
|
super(token);
|
||||||
return funcs.construct(obj, start, end) as any;
|
return funcs.construct(obj, start, end) as any;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,9 +1,9 @@
|
|||||||
import { buffer, func, type InternalBuffer, object, string, symbol } from "../primordials.ts";
|
import { buffer, func, type InternalBuffer, object, string, symbol } from "../primordials.ts";
|
||||||
import { symbols, wrapI } from "../utils.ts";
|
import { symbols, wrapI } from "../utils.ts";
|
||||||
import { Error, TypeError } from "../values/errors.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[]) {
|
export function typedArrayFuncs(perEl: number, constructor: (buff: InternalBuffer, start: number, end: number) => number[]) {
|
||||||
return {
|
return {
|
||||||
@ -56,7 +56,7 @@ export function typedArrayFuncs(perEl: number, constructor: (buff: InternalBuffe
|
|||||||
return constructor(buffer.buff(self * perEl), 0, self);
|
return constructor(buffer.buff(self * perEl), 0, self);
|
||||||
}
|
}
|
||||||
if (self instanceof ArrayBuffer) {
|
if (self instanceof ArrayBuffer) {
|
||||||
const internal = self[abKey];
|
const internal = unwrapAB(self);
|
||||||
if (start === undefined) start = 0;
|
if (start === undefined) start = 0;
|
||||||
if (end === undefined) end = (internal.length / perEl) | 0;
|
if (end === undefined) end = (internal.length / perEl) | 0;
|
||||||
return constructor(internal, start, end);
|
return constructor(internal, start, end);
|
||||||
@ -90,7 +90,7 @@ export function typedArrayFuncs(perEl: number, constructor: (buff: InternalBuffe
|
|||||||
|
|
||||||
export class TypedArray {
|
export class TypedArray {
|
||||||
public get buffer() {
|
public get buffer() {
|
||||||
return getAB(buffer.backer(this as any));
|
return wrapAB(buffer.backer(this as any));
|
||||||
}
|
}
|
||||||
public get byteOffset(): number {
|
public get byteOffset(): number {
|
||||||
throw new Error("abstract");
|
throw new Error("abstract");
|
||||||
@ -212,8 +212,8 @@ export class TypedArray {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public constructor(token?: typeof abstractIgnore) {
|
public constructor(_token?: typeof token) {
|
||||||
if (token !== abstractIgnore) {
|
if (_token !== token) {
|
||||||
throw new TypeError("TypedArray constructor can't be called");
|
throw new TypeError("TypedArray constructor can't be called");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { buffer } from "../primordials.ts";
|
import { buffer } from "../primordials.ts";
|
||||||
import { abstractIgnore, TypedArray, typedArrayFuncs } from "./TypedArray.ts";
|
import { token, TypedArray, typedArrayFuncs } from "./TypedArray.ts";
|
||||||
|
|
||||||
const factory = buffer.uint8;
|
const factory = buffer.uint8;
|
||||||
const funcs = typedArrayFuncs(1, factory);
|
const funcs = typedArrayFuncs(1, factory);
|
||||||
@ -26,7 +26,7 @@ export class Uint8Array extends TypedArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public constructor(obj: any, start?: number, end?: number) {
|
public constructor(obj: any, start?: number, end?: number) {
|
||||||
super(abstractIgnore);
|
super(token);
|
||||||
return funcs.construct(obj, start, end) as any;
|
return funcs.construct(obj, start, end) as any;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,13 +1,11 @@
|
|||||||
import { now, symbol } from "../primordials.ts";
|
import { now, number, symbol } from "../primordials.ts";
|
||||||
|
|
||||||
const timeKey: unique symbol = symbol.makeSymbol("") as any;
|
|
||||||
|
|
||||||
export const Date = (() => {
|
export const Date = (() => {
|
||||||
class Date {
|
class Date {
|
||||||
[timeKey]!: number;
|
#time: number;
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
|
this.#time = number.NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static now() {
|
public static now() {
|
||||||
|
@ -1,51 +1,49 @@
|
|||||||
import { Array } from "../values/array.ts";
|
import { Array } from "../values/array.ts";
|
||||||
import { func, map, symbol } from "../primordials.ts";
|
import { func, map } from "../primordials.ts";
|
||||||
import { symbols } from "../utils.ts";
|
import { symbols } from "../utils.ts";
|
||||||
|
|
||||||
const mapKey: unique symbol = symbol.makeSymbol("Map.impl") as any;
|
|
||||||
|
|
||||||
export class Map<K, V> {
|
export class Map<K, V> {
|
||||||
private [mapKey]: InstanceType<typeof map>;
|
#map: InstanceType<typeof map>;
|
||||||
|
|
||||||
public get size() {
|
public get size() {
|
||||||
return this[mapKey].size();
|
return this.#map.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public get(key: K): V {
|
public get(key: K): V {
|
||||||
return this[mapKey].get(key);
|
return this.#map.get(key);
|
||||||
}
|
}
|
||||||
public has(key: K): boolean {
|
public has(key: K): boolean {
|
||||||
return this[mapKey].has(key);
|
return this.#map.has(key);
|
||||||
}
|
}
|
||||||
public set(key: K, val: V) {
|
public set(key: K, val: V) {
|
||||||
this[mapKey].set(key, val);
|
this.#map.set(key, val);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
public delete(key: K): boolean {
|
public delete(key: K): boolean {
|
||||||
if (!this[mapKey].has(key)) return false;
|
if (!this.#map.has(key)) return false;
|
||||||
else {
|
else {
|
||||||
this[mapKey].delete(key);
|
this.#map.delete(key);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public clear() {
|
public clear() {
|
||||||
this[mapKey].clear();
|
this.#map.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public keys(): K[] {
|
public keys(): K[] {
|
||||||
return this[mapKey].keys();
|
return this.#map.keys();
|
||||||
}
|
}
|
||||||
public values(): V[] {
|
public values(): V[] {
|
||||||
const res = this[mapKey].keys();
|
const res = this.#map.keys();
|
||||||
for (let i = 0; i < res.length; i++) {
|
for (let i = 0; i < res.length; i++) {
|
||||||
res[i] = this[mapKey].get(res[i]);
|
res[i] = this.#map.get(res[i]);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
public entries(): [K, V][] {
|
public entries(): [K, V][] {
|
||||||
const res = this[mapKey].keys();
|
const res = this.#map.keys();
|
||||||
for (let i = 0; i < res.length; i++) {
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
@ -62,7 +60,7 @@ export class Map<K, V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public constructor(iterable?: Iterable<[K, V]>) {
|
public constructor(iterable?: Iterable<[K, V]>) {
|
||||||
const _map = this[mapKey] = new map();
|
const _map = this.#map = new map();
|
||||||
|
|
||||||
if (iterable != null) {
|
if (iterable != null) {
|
||||||
if (Array.isArray(iterable)) {
|
if (Array.isArray(iterable)) {
|
||||||
@ -81,31 +79,31 @@ export class Map<K, V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
export class WeakMap<K, V> {
|
export class WeakMap<K, V> {
|
||||||
private [mapKey]: InstanceType<typeof map>;
|
#map: InstanceType<typeof map>;
|
||||||
|
|
||||||
public get(key: K): V {
|
public get(key: K): V {
|
||||||
return this[mapKey].get(key);
|
return this.#map.get(key);
|
||||||
}
|
}
|
||||||
public has(key: K): boolean {
|
public has(key: K): boolean {
|
||||||
return this[mapKey].has(key);
|
return this.#map.has(key);
|
||||||
}
|
}
|
||||||
public set(key: K, val: V) {
|
public set(key: K, val: V) {
|
||||||
this[mapKey].set(key, val);
|
this.#map.set(key, val);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
public delete(key: K): boolean {
|
public delete(key: K): boolean {
|
||||||
if (!this[mapKey].has(key)) return false;
|
if (!this.#map.has(key)) return false;
|
||||||
else {
|
else {
|
||||||
this[mapKey].delete(key);
|
this.#map.delete(key);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public clear() {
|
public clear() {
|
||||||
this[mapKey].clear();
|
this.#map.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public constructor(iterable?: Iterable<[K, V]>) {
|
public constructor(iterable?: Iterable<[K, V]>) {
|
||||||
const _map = this[mapKey] = new map(true);
|
const _map = this.#map = new map(true);
|
||||||
|
|
||||||
if (iterable != null) {
|
if (iterable != null) {
|
||||||
if (Array.isArray(iterable)) {
|
if (Array.isArray(iterable)) {
|
||||||
@ -123,6 +121,3 @@ export class WeakMap<K, V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func.setCallable(Map, false);
|
|
||||||
func.setCallable(WeakMap, false);
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { func, next, object, symbol } from "../primordials.ts";
|
import { next } from "../primordials.ts";
|
||||||
|
|
||||||
enum PromiseState {
|
enum PromiseState {
|
||||||
Pending = "pend",
|
Pending = "pend",
|
||||||
@ -6,109 +6,106 @@ enum PromiseState {
|
|||||||
Rejected = "rej",
|
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<T>(): Promise<T> {
|
|
||||||
return object.setPrototype({
|
|
||||||
[pState]: PromiseState.Pending,
|
|
||||||
[pFulHandles]: [],
|
|
||||||
[pRejHandles]: [],
|
|
||||||
}, Promise.prototype) as Promise<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fulfill(self: Promise<any>, 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<any>, 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<T>(self: Promise<T>, 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<T> {
|
export class Promise<T> {
|
||||||
public [pState]: PromiseState;
|
static #InternalPromise = function <T>(this: Promise<T>) {
|
||||||
public [pValue]?: T | unknown;
|
this.#state = PromiseState.Pending;
|
||||||
public [pFulHandles]?: ((val: T) => void)[] = [];
|
this.#fulHandles = [];
|
||||||
public [pRejHandles]?: ((val: T) => void)[] = [];
|
this.#rejHandles = [];
|
||||||
|
} as any as new <T>() => Promise<T>;
|
||||||
|
|
||||||
|
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<Res>(ful?: (val: T) => Res, rej?: (err: any) => Res) {
|
public then<Res>(ful?: (val: T) => Res, rej?: (err: any) => Res) {
|
||||||
if (typeof ful !== "function") ful = undefined;
|
if (typeof ful !== "function") ful = undefined;
|
||||||
if (typeof rej !== "function") rej = undefined;
|
if (typeof rej !== "function") rej = undefined;
|
||||||
|
|
||||||
const promise = makePromise<Res>();
|
const promise = new Promise.#InternalPromise<Res>();
|
||||||
|
|
||||||
handle(this,
|
this.#handle(
|
||||||
val => next(() => {
|
val => next(() => {
|
||||||
if (ful == null) fulfill(promise, val);
|
if (ful == null) promise.#fulfill(val);
|
||||||
else {
|
else {
|
||||||
try { fulfill(promise, ful(val)); }
|
try { promise.#fulfill(ful(val)); }
|
||||||
catch (e) { reject(promise, e); }
|
catch (e) { promise.#reject(e); }
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
err => next(() => {
|
err => next(() => {
|
||||||
if (rej == null) reject(promise, err);
|
if (rej == null) promise.#reject(err);
|
||||||
else {
|
else {
|
||||||
try { fulfill(promise, rej(err)); }
|
try { promise.#fulfill(rej(err)); }
|
||||||
catch (e) { reject(promise, e); }
|
catch (e) { promise.#reject(e); }
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@ -134,21 +131,19 @@ export class Promise<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public constructor(fn: (fulfil: (val: T) => void, reject: (err: unknown) => void) => void) {
|
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) {
|
public static resolve(val: any) {
|
||||||
const res = makePromise();
|
const res = new this.#InternalPromise();
|
||||||
fulfill(res, val);
|
res.#fulfill(val);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
public static reject(val: any) {
|
public static reject(val: any) {
|
||||||
const res = makePromise();
|
const res = new this.#InternalPromise();
|
||||||
reject(res, val);
|
res.#reject(val);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func.setCallable(Promise, false);
|
|
||||||
|
@ -1,42 +1,40 @@
|
|||||||
import { Array } from "../values/array.ts";
|
import { Array } from "../values/array.ts";
|
||||||
import { func, map, symbol } from "../primordials.ts";
|
import { func, map } from "../primordials.ts";
|
||||||
import { symbols } from "../utils.ts";
|
import { symbols } from "../utils.ts";
|
||||||
|
|
||||||
const mapKey: unique symbol = symbol.makeSymbol("Set.impl") as any;
|
|
||||||
|
|
||||||
export class Set<T> {
|
export class Set<T> {
|
||||||
private [mapKey]: InstanceType<typeof map>;
|
#map: InstanceType<typeof map>;
|
||||||
|
|
||||||
public get size() {
|
public get size() {
|
||||||
return this[mapKey].size();
|
return this.#map.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public has(key: T): boolean {
|
public has(key: T): boolean {
|
||||||
return this[mapKey].has(key);
|
return this.#map.has(key);
|
||||||
}
|
}
|
||||||
public add(val: T) {
|
public add(val: T) {
|
||||||
this[mapKey].set(val, true);
|
this.#map.set(val, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
public delete(val: T): boolean {
|
public delete(val: T): boolean {
|
||||||
if (!this[mapKey].has(val)) return false;
|
if (!this.#map.has(val)) return false;
|
||||||
else {
|
else {
|
||||||
this[mapKey].delete(val);
|
this.#map.delete(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public clear() {
|
public clear() {
|
||||||
this[mapKey].clear();
|
this.#map.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public keys(): T[] {
|
public keys(): T[] {
|
||||||
return this[mapKey].keys();
|
return this.#map.keys();
|
||||||
}
|
}
|
||||||
public values(): T[] {
|
public values(): T[] {
|
||||||
return this[mapKey].keys();
|
return this.#map.keys();
|
||||||
}
|
}
|
||||||
public entries(): [T, T][] {
|
public entries(): [T, T][] {
|
||||||
const res = this[mapKey].keys();
|
const res = this.#map.keys();
|
||||||
|
|
||||||
for (let i = 0; i < res.length; i++) {
|
for (let i = 0; i < res.length; i++) {
|
||||||
res[i] = [res[i], res[i]];
|
res[i] = [res[i], res[i]];
|
||||||
@ -57,7 +55,7 @@ export class Set<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public constructor(iterable?: Iterable<T>) {
|
public constructor(iterable?: Iterable<T>) {
|
||||||
const _map = this[mapKey] = new map();
|
const _map = this.#map = new map();
|
||||||
|
|
||||||
if (iterable != null) {
|
if (iterable != null) {
|
||||||
if (Array.isArray(iterable)) {
|
if (Array.isArray(iterable)) {
|
||||||
@ -77,28 +75,28 @@ export class Set<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class WeakSet<T> {
|
export class WeakSet<T> {
|
||||||
private [mapKey]: InstanceType<typeof map>;
|
#map: InstanceType<typeof map>;
|
||||||
|
|
||||||
public has(key: T): boolean {
|
public has(key: T): boolean {
|
||||||
return this[mapKey].has(key);
|
return this.#map.has(key);
|
||||||
}
|
}
|
||||||
public add(val: T) {
|
public add(val: T) {
|
||||||
this[mapKey].set(val, true);
|
this.#map.set(val, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
public delete(val: T): boolean {
|
public delete(val: T): boolean {
|
||||||
if (!this[mapKey].has(val)) return false;
|
if (!this.#map.has(val)) return false;
|
||||||
else {
|
else {
|
||||||
this[mapKey].delete(val);
|
this.#map.delete(val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public clear() {
|
public clear() {
|
||||||
this[mapKey].clear();
|
this.#map.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public constructor(iterable?: Iterable<T>) {
|
public constructor(iterable?: Iterable<T>) {
|
||||||
const _map = this[mapKey] = new map(true);
|
const _map = this.#map = new map(true);
|
||||||
|
|
||||||
if (iterable != null) {
|
if (iterable != null) {
|
||||||
if (Array.isArray(iterable)) {
|
if (Array.isArray(iterable)) {
|
||||||
@ -116,6 +114,3 @@ export class WeakSet<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func.setCallable(Set, false);
|
|
||||||
func.setCallable(WeakSet, false);
|
|
||||||
|
@ -4,6 +4,14 @@ export interface InternalBuffer {
|
|||||||
length: number;
|
length: number;
|
||||||
[buffSymbol]: "buffer";
|
[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 {
|
export interface SymbolPrimordials {
|
||||||
makeSymbol(name: string): symbol;
|
makeSymbol(name: string): symbol;
|
||||||
@ -82,6 +90,9 @@ export interface JSONPrimordials {
|
|||||||
parse(data: string): any;
|
parse(data: string): any;
|
||||||
stringify(data: any): string;
|
stringify(data: any): string;
|
||||||
}
|
}
|
||||||
|
export interface NetPrimordials {
|
||||||
|
server(): InternalServer;
|
||||||
|
}
|
||||||
|
|
||||||
export interface Primordials {
|
export interface Primordials {
|
||||||
symbol: SymbolPrimordials;
|
symbol: SymbolPrimordials;
|
||||||
@ -91,6 +102,7 @@ export interface Primordials {
|
|||||||
function: FunctionPrimordials;
|
function: FunctionPrimordials;
|
||||||
json: JSONPrimordials;
|
json: JSONPrimordials;
|
||||||
buffer: BufferPrimordials;
|
buffer: BufferPrimordials;
|
||||||
|
net: NetPrimordials;
|
||||||
map: new (weak?: boolean) => {
|
map: new (weak?: boolean) => {
|
||||||
get(key: any): any;
|
get(key: any): any;
|
||||||
has(key: any): boolean;
|
has(key: any): boolean;
|
||||||
@ -127,6 +139,7 @@ export const {
|
|||||||
buffer,
|
buffer,
|
||||||
function: func,
|
function: func,
|
||||||
json,
|
json,
|
||||||
|
net: socket,
|
||||||
map,
|
map,
|
||||||
regex,
|
regex,
|
||||||
setGlobalPrototypes,
|
setGlobalPrototypes,
|
||||||
@ -138,4 +151,5 @@ export const {
|
|||||||
print,
|
print,
|
||||||
} = primordials;
|
} = primordials;
|
||||||
|
|
||||||
export type regex = InstanceType<typeof regex>;
|
export type regex = InstanceType<typeof regex>;
|
||||||
|
export const self = (globalThis as any);
|
||||||
|
63
lib/src/stdlib/sockets.ts
Normal file
63
lib/src/stdlib/sockets.ts
Normal file
@ -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<void>((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<void>((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;
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,12 @@
|
|||||||
import { func, regex, symbol } from "../primordials.ts";
|
import { func, regex } from "../primordials.ts";
|
||||||
import { String } from "./string.ts";
|
import { String } from "./string.ts";
|
||||||
import { type ReplaceRange } from "../utils.ts";
|
import { type ReplaceRange } from "../utils.ts";
|
||||||
import { applyReplaces } from "../utils.ts";
|
import { applyReplaces } from "../utils.ts";
|
||||||
import { applySplits } from "../utils.ts";
|
import { applySplits } from "../utils.ts";
|
||||||
import { symbols } from "../utils.ts";
|
import { symbols } from "../utils.ts";
|
||||||
|
|
||||||
const regexKey: unique symbol = symbol.makeSymbol("RegExp.impl") as any;
|
|
||||||
|
|
||||||
export class RegExp {
|
export class RegExp {
|
||||||
private [regexKey]!: InstanceType<typeof regex>;
|
#regex!: InstanceType<typeof regex>;
|
||||||
|
|
||||||
public readonly source!: string;
|
public readonly source!: string;
|
||||||
public readonly flags!: string;
|
public readonly flags!: string;
|
||||||
@ -70,14 +68,14 @@ export class RegExp {
|
|||||||
this.unicodeSets = unicodeSets;
|
this.unicodeSets = unicodeSets;
|
||||||
this.sticky = sticky;
|
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) {
|
public exec(target: string) {
|
||||||
const useLast = this.global || this.sticky;
|
const useLast = this.global || this.sticky;
|
||||||
const start = useLast ? this.lastIndex : 0;
|
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 (match != null && !(this.sticky && match.matches.index !== start)) {
|
||||||
if (useLast) this.lastIndex = match.end;
|
if (useLast) this.lastIndex = match.end;
|
||||||
return match.matches;
|
return match.matches;
|
||||||
@ -92,7 +90,7 @@ export class RegExp {
|
|||||||
|
|
||||||
public [symbols.split](target: string, limit?: number) {
|
public [symbols.split](target: string, limit?: number) {
|
||||||
return applySplits(target, limit, offset => {
|
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;
|
if (val == null) return undefined;
|
||||||
|
|
||||||
return { start: val.matches.index!, end: val.end };
|
return { start: val.matches.index!, end: val.end };
|
||||||
@ -100,7 +98,7 @@ export class RegExp {
|
|||||||
}
|
}
|
||||||
public [symbols.replace](target: string, replacer: any) {
|
public [symbols.replace](target: string, replacer: any) {
|
||||||
const matches: ReplaceRange[] = [];
|
const matches: ReplaceRange[] = [];
|
||||||
const regex = this[regexKey];
|
const regex = this.#regex;
|
||||||
|
|
||||||
if (this.global) {
|
if (this.global) {
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
@ -136,3 +134,6 @@ export class RegExp {
|
|||||||
return applyReplaces(target, matches, replacer, regex.groupCount() + 1);
|
return applyReplaces(target, matches, replacer, regex.groupCount() + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func.setCallable(RegExp, true);
|
||||||
|
func.setConstructable(RegExp, true);
|
||||||
|
Loading…
Reference in New Issue
Block a user