@php-wasm/logger 0.6.6 → 0.6.8

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/index.d.ts CHANGED
@@ -1 +1 @@
1
- export * from './logger';
1
+ export * from './lib/logger';
package/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class i{constructor(e){this.LOG_PREFIX="Playground",this.windowConnected=!1,this.lastPHPLogLength=0,this.errorLogPath="/wordpress/wp-content/debug.log",e&&(this.errorLogPath=e)}async getRequestPhpErrorLog(e){return await e.fileExists(this.errorLogPath)?await e.readFileAsText(this.errorLogPath):""}logWindowError(e){this.log(`${e.message} in ${e.filename} on line ${e.lineno}:${e.colno}`,"fatal")}logUnhandledRejection(e){this.log(`${e.reason.stack}`,"fatal")}addWindowErrorListener(){this.windowConnected||typeof window>"u"||(window.addEventListener("error",this.logWindowError.bind(this)),window.addEventListener("unhandledrejection",this.logUnhandledRejection.bind(this)),window.addEventListener("rejectionhandled",this.logUnhandledRejection.bind(this)),this.windowConnected=!0)}addPlaygroundRequestEndListener(e){e.addEventListener("request.end",async()=>{const t=await this.getRequestPhpErrorLog(e);t.length>this.lastPHPLogLength&&(this.logRaw(t.substring(this.lastPHPLogLength)),this.lastPHPLogLength=t.length)})}formatLogDate(e){const t=new Intl.DateTimeFormat("en-GB",{year:"numeric",month:"short",day:"2-digit",timeZone:"UTC"}).format(e).replace(/ /g,"-"),n=new Intl.DateTimeFormat("en-GB",{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1,timeZone:"UTC",timeZoneName:"short"}).format(e);return t+" "+n}formatMessage(e,t){return`[${this.formatLogDate(new Date)}] ${this.LOG_PREFIX} ${t}: ${e}`}log(e,t){t===void 0&&(t="info");const n=this.formatMessage(e,t);this.logRaw(n)}logRaw(e){console.debug(e)}}const r=new i;function s(o){o.addWindowErrorListener()}function a(o,e){o.addPlaygroundRequestEndListener(e)}exports.Logger=i;exports.collectPhpLogs=a;exports.collectWindowErrors=s;exports.logger=r;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=function(){var o;return typeof process<"u"&&((o=process.release)==null?void 0:o.name)==="node"?"NODE":typeof window<"u"?"WEB":typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?"WORKER":"NODE"}();if(u==="NODE"){let o=function(e){return new Promise(function(r,n){e.onload=e.onerror=function(s){e.onload=e.onerror=null,s.type==="load"?r(e.result):n(new Error("Failed to read the blob/file"))}})},t=function(){const e=new Uint8Array([1,2,3,4]),n=new File([e],"test").stream();try{return n.getReader({mode:"byob"}),!0}catch{return!1}};if(typeof File>"u"){class e extends Blob{constructor(n,s,a){super(n);let i;a!=null&&a.lastModified&&(i=new Date),(!i||isNaN(i.getFullYear()))&&(i=new Date),this.lastModifiedDate=i,this.lastModified=i.getMilliseconds(),this.name=s||""}}global.File=e}typeof Blob.prototype.arrayBuffer>"u"&&(Blob.prototype.arrayBuffer=function(){const r=new FileReader;return r.readAsArrayBuffer(this),o(r)}),typeof Blob.prototype.text>"u"&&(Blob.prototype.text=function(){const r=new FileReader;return r.readAsText(this),o(r)}),(typeof Blob.prototype.stream>"u"||!t())&&(Blob.prototype.stream=function(){let e=0;const r=this;return new ReadableStream({type:"bytes",autoAllocateChunkSize:512*1024,async pull(n){const s=n.byobRequest.view,i=await r.slice(e,e+s.byteLength).arrayBuffer(),d=new Uint8Array(i);new Uint8Array(s.buffer).set(d);const l=d.byteLength;n.byobRequest.respond(l),e+=l,e>=r.size&&n.close()}})})}if(u==="NODE"&&typeof CustomEvent>"u"){class o extends Event{constructor(e,r={}){super(e,r),this.detail=r.detail}initCustomEvent(){}}globalThis.CustomEvent=o}class f extends EventTarget{constructor(t){super(),this.fatalErrorEvent="playground-fatal-error",this.logs=[],this.windowConnected=!1,this.lastPHPLogLength=0,this.errorLogPath="/wordpress/wp-content/debug.log",t&&(this.errorLogPath=t)}async getRequestPhpErrorLog(t){return await t.fileExists(this.errorLogPath)?await t.readFileAsText(this.errorLogPath):""}logWindowError(t){this.log(`${t.message} in ${t.filename} on line ${t.lineno}:${t.colno}`,"Error")}logUnhandledRejection(t){this.log(`${t.reason.stack}`,"Error")}addWindowErrorListener(){this.windowConnected||typeof window>"u"||(window.addEventListener("error",this.logWindowError.bind(this)),window.addEventListener("unhandledrejection",this.logUnhandledRejection.bind(this)),window.addEventListener("rejectionhandled",this.logUnhandledRejection.bind(this)),this.windowConnected=!0)}addPlaygroundRequestEndListener(t){t.addEventListener("request.end",async()=>{const e=await this.getRequestPhpErrorLog(t);e.length>this.lastPHPLogLength&&(this.logRaw(e.substring(this.lastPHPLogLength)),this.lastPHPLogLength=e.length)}),t.addEventListener("request.error",e=>{e=e,e.error&&(this.log(`${e.error.message} ${e.error.stack}`,"Fatal","PHP-WASM"),this.dispatchEvent(new CustomEvent(this.fatalErrorEvent,{detail:{logs:this.getLogs()}})))})}formatLogDate(t){const e=new Intl.DateTimeFormat("en-GB",{year:"numeric",month:"short",day:"2-digit",timeZone:"UTC"}).format(t).replace(/ /g,"-"),r=new Intl.DateTimeFormat("en-GB",{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1,timeZone:"UTC",timeZoneName:"short"}).format(t);return e+" "+r}formatMessage(t,e,r){return`[${this.formatLogDate(new Date)}] ${r} ${e}: ${t}`}log(t,e,r){e===void 0&&(e="Info");const n=this.formatMessage(t,e,r??"Playground");this.logRaw(n)}logRaw(t){this.logs.push(t),console.debug(t)}getLogs(){return this.logs}}const c=new f;function g(o){o.addWindowErrorListener()}function h(o,t){o.addPlaygroundRequestEndListener(t)}function w(o,t){o.addEventListener(o.fatalErrorEvent,t)}exports.Logger=f;exports.addFatalErrorListener=w;exports.collectPhpLogs=h;exports.collectWindowErrors=g;exports.logger=c;
package/index.mjs CHANGED
@@ -1,6 +1,75 @@
1
- class i {
1
+ const f = function() {
2
+ var n;
3
+ return typeof process < "u" && ((n = process.release) == null ? void 0 : n.name) === "node" ? "NODE" : typeof window < "u" ? "WEB" : (
4
+ // @ts-ignore
5
+ typeof WorkerGlobalScope < "u" && // @ts-ignore
6
+ self instanceof WorkerGlobalScope ? "WORKER" : "NODE"
7
+ );
8
+ }();
9
+ if (f === "NODE") {
10
+ let n = function(e) {
11
+ return new Promise(function(r, o) {
12
+ e.onload = e.onerror = function(s) {
13
+ e.onload = e.onerror = null, s.type === "load" ? r(e.result) : o(new Error("Failed to read the blob/file"));
14
+ };
15
+ });
16
+ }, t = function() {
17
+ const e = new Uint8Array([1, 2, 3, 4]), o = new File([e], "test").stream();
18
+ try {
19
+ return o.getReader({ mode: "byob" }), !0;
20
+ } catch {
21
+ return !1;
22
+ }
23
+ };
24
+ if (typeof File > "u") {
25
+ class e extends Blob {
26
+ constructor(o, s, a) {
27
+ super(o);
28
+ let i;
29
+ a != null && a.lastModified && (i = /* @__PURE__ */ new Date()), (!i || isNaN(i.getFullYear())) && (i = /* @__PURE__ */ new Date()), this.lastModifiedDate = i, this.lastModified = i.getMilliseconds(), this.name = s || "";
30
+ }
31
+ }
32
+ global.File = e;
33
+ }
34
+ typeof Blob.prototype.arrayBuffer > "u" && (Blob.prototype.arrayBuffer = function() {
35
+ const r = new FileReader();
36
+ return r.readAsArrayBuffer(this), n(r);
37
+ }), typeof Blob.prototype.text > "u" && (Blob.prototype.text = function() {
38
+ const r = new FileReader();
39
+ return r.readAsText(this), n(r);
40
+ }), (typeof Blob.prototype.stream > "u" || !t()) && (Blob.prototype.stream = function() {
41
+ let e = 0;
42
+ const r = this;
43
+ return new ReadableStream({
44
+ type: "bytes",
45
+ // 0.5 MB seems like a reasonable chunk size, let's adjust
46
+ // this if needed.
47
+ autoAllocateChunkSize: 512 * 1024,
48
+ async pull(o) {
49
+ const s = o.byobRequest.view, i = await r.slice(
50
+ e,
51
+ e + s.byteLength
52
+ ).arrayBuffer(), d = new Uint8Array(i);
53
+ new Uint8Array(s.buffer).set(d);
54
+ const l = d.byteLength;
55
+ o.byobRequest.respond(l), e += l, e >= r.size && o.close();
56
+ }
57
+ });
58
+ });
59
+ }
60
+ if (f === "NODE" && typeof CustomEvent > "u") {
61
+ class n extends Event {
62
+ constructor(e, r = {}) {
63
+ super(e, r), this.detail = r.detail;
64
+ }
65
+ initCustomEvent() {
66
+ }
67
+ }
68
+ globalThis.CustomEvent = n;
69
+ }
70
+ class u extends EventTarget {
2
71
  constructor(t) {
3
- this.LOG_PREFIX = "Playground", this.windowConnected = !1, this.lastPHPLogLength = 0, this.errorLogPath = "/wordpress/wp-content/debug.log", t && (this.errorLogPath = t);
72
+ super(), this.fatalErrorEvent = "playground-fatal-error", this.logs = [], this.windowConnected = !1, this.lastPHPLogLength = 0, this.errorLogPath = "/wordpress/wp-content/debug.log", t && (this.errorLogPath = t);
4
73
  }
5
74
  /**
6
75
  * Read the WordPress debug.log file and return its content.
@@ -19,7 +88,7 @@ class i {
19
88
  logWindowError(t) {
20
89
  this.log(
21
90
  `${t.message} in ${t.filename} on line ${t.lineno}:${t.colno}`,
22
- "fatal"
91
+ "Error"
23
92
  );
24
93
  }
25
94
  /**
@@ -28,7 +97,7 @@ class i {
28
97
  * @param PromiseRejectionEvent event
29
98
  */
30
99
  logUnhandledRejection(t) {
31
- this.log(`${t.reason.stack}`, "fatal");
100
+ this.log(`${t.reason.stack}`, "Error");
32
101
  }
33
102
  /**
34
103
  * Register a listener for the window error events and log the data.
@@ -50,6 +119,18 @@ class i {
50
119
  t.addEventListener("request.end", async () => {
51
120
  const e = await this.getRequestPhpErrorLog(t);
52
121
  e.length > this.lastPHPLogLength && (this.logRaw(e.substring(this.lastPHPLogLength)), this.lastPHPLogLength = e.length);
122
+ }), t.addEventListener("request.error", (e) => {
123
+ e = e, e.error && (this.log(
124
+ `${e.error.message} ${e.error.stack}`,
125
+ "Fatal",
126
+ "PHP-WASM"
127
+ ), this.dispatchEvent(
128
+ new CustomEvent(this.fatalErrorEvent, {
129
+ detail: {
130
+ logs: this.getLogs()
131
+ }
132
+ })
133
+ ));
53
134
  });
54
135
  }
55
136
  /**
@@ -64,7 +145,7 @@ class i {
64
145
  month: "short",
65
146
  day: "2-digit",
66
147
  timeZone: "UTC"
67
- }).format(t).replace(/ /g, "-"), n = new Intl.DateTimeFormat("en-GB", {
148
+ }).format(t).replace(/ /g, "-"), r = new Intl.DateTimeFormat("en-GB", {
68
149
  hour: "2-digit",
69
150
  minute: "2-digit",
70
151
  second: "2-digit",
@@ -72,44 +153,61 @@ class i {
72
153
  timeZone: "UTC",
73
154
  timeZoneName: "short"
74
155
  }).format(t);
75
- return e + " " + n;
156
+ return e + " " + r;
76
157
  }
77
158
  /**
78
159
  * Format log message and severity and log it.
79
160
  * @param string message
80
161
  * @param LogSeverity severity
162
+ * @param string prefix
81
163
  */
82
- formatMessage(t, e) {
83
- return `[${this.formatLogDate(/* @__PURE__ */ new Date())}] ${this.LOG_PREFIX} ${e}: ${t}`;
164
+ formatMessage(t, e, r) {
165
+ return `[${this.formatLogDate(/* @__PURE__ */ new Date())}] ${r} ${e}: ${t}`;
84
166
  }
85
167
  /**
86
168
  * Log message with severity and timestamp.
87
169
  * @param string message
88
170
  * @param LogSeverity severity
171
+ * @param string prefix
89
172
  */
90
- log(t, e) {
91
- e === void 0 && (e = "info");
92
- const n = this.formatMessage(t, e);
93
- this.logRaw(n);
173
+ log(t, e, r) {
174
+ e === void 0 && (e = "Info");
175
+ const o = this.formatMessage(
176
+ t,
177
+ e,
178
+ r ?? "Playground"
179
+ );
180
+ this.logRaw(o);
94
181
  }
95
182
  /**
96
183
  * Log message without severity and timestamp.
97
184
  * @param string log
98
185
  */
99
186
  logRaw(t) {
100
- console.debug(t);
187
+ this.logs.push(t), console.debug(t);
101
188
  }
189
+ /**
190
+ * Get all logs.
191
+ * @returns string[]
192
+ */
193
+ getLogs() {
194
+ return this.logs;
195
+ }
196
+ }
197
+ const c = new u();
198
+ function h(n) {
199
+ n.addWindowErrorListener();
102
200
  }
103
- const r = new i();
104
- function s(o) {
105
- o.addWindowErrorListener();
201
+ function g(n, t) {
202
+ n.addPlaygroundRequestEndListener(t);
106
203
  }
107
- function a(o, t) {
108
- o.addPlaygroundRequestEndListener(t);
204
+ function w(n, t) {
205
+ n.addEventListener(n.fatalErrorEvent, t);
109
206
  }
110
207
  export {
111
- i as Logger,
112
- a as collectPhpLogs,
113
- s as collectWindowErrors,
114
- r as logger
208
+ u as Logger,
209
+ w as addFatalErrorListener,
210
+ g as collectPhpLogs,
211
+ h as collectWindowErrors,
212
+ c as logger
115
213
  };
@@ -1,13 +1,21 @@
1
- import { UniversalPHP } from '../../universal/src/index.ts/src/lib/universal-php';
1
+ import { UniversalPHP } from '../../../universal/src/index.ts/src/lib/universal-php';
2
2
  /**
3
3
  * Log severity levels.
4
4
  */
5
- export type LogSeverity = 'debug' | 'info' | 'warn' | 'error' | 'fatal';
5
+ export type LogSeverity = 'Debug' | 'Info' | 'Warn' | 'Error' | 'Fatal';
6
+ /**
7
+ * Log prefix.
8
+ */
9
+ export type LogPrefix = 'Playground' | 'PHP-WASM';
6
10
  /**
7
11
  * A logger for Playground.
8
12
  */
9
- export declare class Logger {
10
- private readonly LOG_PREFIX;
13
+ export declare class Logger extends EventTarget {
14
+ readonly fatalErrorEvent = "playground-fatal-error";
15
+ /**
16
+ * Log messages
17
+ */
18
+ private logs;
11
19
  /**
12
20
  * Whether the window events are connected.
13
21
  */
@@ -60,19 +68,26 @@ export declare class Logger {
60
68
  * Format log message and severity and log it.
61
69
  * @param string message
62
70
  * @param LogSeverity severity
71
+ * @param string prefix
63
72
  */
64
- formatMessage(message: string, severity: LogSeverity): string;
73
+ formatMessage(message: string, severity: LogSeverity, prefix: string): string;
65
74
  /**
66
75
  * Log message with severity and timestamp.
67
76
  * @param string message
68
77
  * @param LogSeverity severity
78
+ * @param string prefix
69
79
  */
70
- log(message: string, severity?: LogSeverity): void;
80
+ log(message: string, severity?: LogSeverity, prefix?: LogPrefix): void;
71
81
  /**
72
82
  * Log message without severity and timestamp.
73
83
  * @param string log
74
84
  */
75
85
  logRaw(log: string): void;
86
+ /**
87
+ * Get all logs.
88
+ * @returns string[]
89
+ */
90
+ getLogs(): string[];
76
91
  }
77
92
  /**
78
93
  * The logger instance.
@@ -89,3 +104,12 @@ export declare function collectWindowErrors(loggerInstance: Logger): void;
89
104
  * @param loggerInstance The logger instance
90
105
  */
91
106
  export declare function collectPhpLogs(loggerInstance: Logger, playground: UniversalPHP): void;
107
+ /**
108
+ * Add a listener for the fatal Playground errors.
109
+ * These errors include Playground errors like Asyncify errors. PHP errors won't trigger this event.
110
+ * The callback function will receive an Event object with logs in the detail property.
111
+ *
112
+ * @param loggerInstance The logger instance
113
+ * @param callback The callback function
114
+ */
115
+ export declare function addFatalErrorListener(loggerInstance: Logger, callback: EventListenerOrEventListenerObject): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@php-wasm/logger",
3
- "version": "0.6.6",
3
+ "version": "0.6.8",
4
4
  "description": "A logger for PHP-wasm clients like Playground and WP-now.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,5 +25,5 @@
25
25
  "node": ">=18.18.2",
26
26
  "npm": ">=8.11.0"
27
27
  },
28
- "gitHead": "90f82ca946f8573b358c1320be0b6b8674f67cfc"
28
+ "gitHead": "cb7b1af260489022238495a2fc0d96f767a1294a"
29
29
  }