Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
titaniumnetwork-dev
GitHub Repository: titaniumnetwork-dev/Ultraviolet
Path: blob/main/src/client/index.js
304 views
1
import DocumentHook from "./dom/document.js";
2
import ElementApi from "./dom/element.js";
3
import NodeApi from "./dom/node.js";
4
import AttrApi from "./dom/attr.js";
5
import FunctionHook from "./native/function.js";
6
import ObjectHook from "./native/object.js";
7
import Fetch from "./requests/fetch.js";
8
import Xhr from "./requests/xhr.js";
9
import EventSourceApi from "./requests/eventsource.js";
10
import History from "./history.js";
11
import LocationApi from "./location.js";
12
import MessageApi from "./message.js";
13
import NavigatorApi from "./navigator.js";
14
import Workers from "./worker.js";
15
import URLApi from "./url.js";
16
import EventEmitter from "events";
17
import StorageApi from "./storage.js";
18
import StyleApi from "./dom/style.js";
19
import IDBApi from "./idb.js";
20
import WebSocketApi from "./requests/websocket.js";
21
22
/**
23
* @template {Function} [T=Function]
24
* @typedef {(fn: T, that: any, args: any[]) => {}} WrapFun
25
*/
26
27
/**
28
* @typedef {object} WrapPropertyDescriptor
29
* @property {WrapFun} [get]
30
* @property {WrapFun} [set]
31
*/
32
33
class UVClient extends EventEmitter {
34
/**
35
*
36
* @param {typeof globalThis} window
37
* @param {import('@mercuryworkshop/bare-mux').BareClient} bareClient
38
* @param {boolean} worker
39
*/
40
constructor(window = self, bareClient, worker = !window.window) {
41
super();
42
/**
43
* @type {typeof globalThis}
44
*/
45
this.window = window;
46
this.nativeMethods = {
47
fnToString: this.window.Function.prototype.toString,
48
defineProperty: this.window.Object.defineProperty,
49
getOwnPropertyDescriptor: this.window.Object.getOwnPropertyDescriptor,
50
getOwnPropertyDescriptors: this.window.Object.getOwnPropertyDescriptors,
51
getOwnPropertyNames: this.window.Object.getOwnPropertyNames,
52
keys: this.window.Object.keys,
53
getOwnPropertySymbols: this.window.Object.getOwnPropertySymbols,
54
isArray: this.window.Array.isArray,
55
setPrototypeOf: this.window.Object.setPrototypeOf,
56
isExtensible: this.window.Object.isExtensible,
57
Map: this.window.Map,
58
Proxy: this.window.Proxy,
59
};
60
this.worker = worker;
61
this.bareClient = bareClient;
62
this.fetch = new Fetch(this);
63
this.xhr = new Xhr(this);
64
this.idb = new IDBApi(this);
65
this.history = new History(this);
66
this.element = new ElementApi(this);
67
this.node = new NodeApi(this);
68
this.document = new DocumentHook(this);
69
this.function = new FunctionHook(this);
70
this.object = new ObjectHook(this);
71
this.websocket = new WebSocketApi(this);
72
this.message = new MessageApi(this);
73
this.navigator = new NavigatorApi(this);
74
this.eventSource = new EventSourceApi(this);
75
this.attribute = new AttrApi(this);
76
this.url = new URLApi(this);
77
this.workers = new Workers(this);
78
this.location = new LocationApi(this);
79
this.storage = new StorageApi(this);
80
this.style = new StyleApi(this);
81
}
82
/**
83
*
84
* @param {*} obj
85
* @param {PropertyKey} prop
86
* @param {WrapFun} wrapper
87
* @param {boolean} [construct]
88
* @returns
89
*/
90
override(obj, prop, wrapper, construct) {
91
// if (!(prop in obj)) return false;
92
const wrapped = this.wrap(obj, prop, wrapper, construct);
93
obj[prop] = wrapped;
94
return wrapped;
95
}
96
/**
97
*
98
* @param {*} obj
99
* @param {PropertyKey} prop
100
* @param {WrapPropertyDescriptor} [wrapObj]
101
* @returns
102
*/
103
overrideDescriptor(obj, prop, wrapObj = {}) {
104
const wrapped = this.wrapDescriptor(obj, prop, wrapObj);
105
if (!wrapped) return {};
106
this.nativeMethods.defineProperty(obj, prop, wrapped);
107
return wrapped;
108
}
109
110
/**
111
*
112
* @template T
113
* @param {*} obj
114
* @param {PropertyKey} prop
115
* @param {WrapFun<T>} wrap
116
* @param {boolean} [construct]
117
* @returns {T}
118
*/
119
wrap(obj, prop, wrap, construct = false) {
120
const fn = obj[prop];
121
if (!fn) return fn;
122
const wrapped =
123
"prototype" in fn
124
? function attach() {
125
return wrap(fn, this, [...arguments]);
126
}
127
: {
128
attach() {
129
return wrap(fn, this, [...arguments]);
130
},
131
}.attach;
132
133
if (construct) {
134
wrapped.prototype = fn.prototype;
135
wrapped.prototype.constructor = wrapped;
136
}
137
138
this.emit("wrap", fn, wrapped, construct);
139
140
return wrapped;
141
}
142
/**
143
*
144
* @param {*} obj
145
* @param {PropertyKey} prop
146
* @param {WrapPropertyDescriptor} [wrapObj]
147
* @returns
148
*/
149
wrapDescriptor(obj, prop, wrapObj = {}) {
150
const descriptor = this.nativeMethods.getOwnPropertyDescriptor(obj, prop);
151
if (!descriptor) return false;
152
for (let key in wrapObj) {
153
if (key in descriptor) {
154
if (key === "get" || key === "set") {
155
descriptor[key] = this.wrap(descriptor, key, wrapObj[key]);
156
} else {
157
descriptor[key] =
158
typeof wrapObj[key] == "function"
159
? wrapObj[key](descriptor[key])
160
: wrapObj[key];
161
}
162
}
163
}
164
return descriptor;
165
}
166
}
167
168
export default UVClient;
169
if (typeof self === "object") self.UVClient = UVClient;
170
171