create-prisma-php-app 4.1.0-beta.7 → 4.1.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/dist/bootstrap.php +263 -135
- package/dist/index.js +1 -1
- package/dist/prisma-php.js +1 -1
- package/dist/public/js/main.js +1 -2
- package/dist/public/js/pp-reactive-v1.js +1 -42
- package/dist/settings/bs-config.ts +16 -3
- package/dist/settings/vite-plugins/generate-global-types.ts +246 -0
- package/dist/src/Lib/Auth/Auth.php +16 -23
- package/dist/src/app/layout.php +2 -3
- package/dist/ts/main.ts +0 -1
- package/dist/tsconfig.json +1 -1
- package/dist/vite.config.ts +20 -6
- package/package.json +4 -4
- package/dist/public/js/pp-loop.js +0 -1
- package/dist/public/js/pp-portal.js +0 -1
- package/dist/public/js/pp-utilities.js +0 -1
- /package/dist/{src/app → public}/favicon.ico +0 -0
|
@@ -3,7 +3,7 @@ import { writeFileSync, existsSync, mkdirSync } from "fs";
|
|
|
3
3
|
import browserSync, { BrowserSyncInstance } from "browser-sync";
|
|
4
4
|
import prismaPhpConfigJson from "../prisma-php.json";
|
|
5
5
|
import { generateFileListJson } from "./files-list.js";
|
|
6
|
-
import { join, dirname } from "path";
|
|
6
|
+
import { join, dirname, relative } from "path";
|
|
7
7
|
import { getFileMeta, PUBLIC_DIR, SRC_DIR } from "./utils.js";
|
|
8
8
|
import { updateAllClassLogs } from "./class-log.js";
|
|
9
9
|
import {
|
|
@@ -15,9 +15,10 @@ import { checkComponentImports } from "./component-import-checker";
|
|
|
15
15
|
import { DebouncedWorker, createSrcWatcher, DEFAULT_AWF } from "./utils.js";
|
|
16
16
|
|
|
17
17
|
const { __dirname } = getFileMeta();
|
|
18
|
-
|
|
19
18
|
const bs: BrowserSyncInstance = browserSync.create();
|
|
20
19
|
|
|
20
|
+
const PUBLIC_IGNORE_DIRS = [''];
|
|
21
|
+
|
|
21
22
|
const pipeline = new DebouncedWorker(
|
|
22
23
|
async () => {
|
|
23
24
|
await generateFileListJson();
|
|
@@ -68,7 +69,19 @@ createSrcWatcher(join(SRC_DIR, "**", "*"), {
|
|
|
68
69
|
});
|
|
69
70
|
|
|
70
71
|
createSrcWatcher(join(PUBLIC_DIR, "**", "*"), {
|
|
71
|
-
onEvent: (_ev,
|
|
72
|
+
onEvent: (_ev, abs, _) => {
|
|
73
|
+
const relFromPublic = relative(PUBLIC_DIR, abs);
|
|
74
|
+
const normalized = relFromPublic.replace(/\\/g, "/");
|
|
75
|
+
|
|
76
|
+
const segments = normalized.split("/").filter(Boolean);
|
|
77
|
+
const firstSegment = segments[0] || "";
|
|
78
|
+
|
|
79
|
+
if (PUBLIC_IGNORE_DIRS.includes(firstSegment)) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
publicPipeline.schedule(relFromPublic);
|
|
84
|
+
},
|
|
72
85
|
awaitWriteFinish: DEFAULT_AWF,
|
|
73
86
|
logPrefix: "watch-public",
|
|
74
87
|
usePolling: true,
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { Plugin } from "vite";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { writeFileSync, mkdirSync, existsSync, readFileSync } from "fs";
|
|
4
|
+
import ts from "typescript";
|
|
5
|
+
|
|
6
|
+
export function generateGlobalTypes(): Plugin {
|
|
7
|
+
const dtsPath = path.resolve(process.cwd(), ".pp", "global-functions.d.ts");
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
name: "generate-global-types",
|
|
11
|
+
|
|
12
|
+
buildStart() {
|
|
13
|
+
const mainPath = path.resolve(process.cwd(), "ts", "main.ts");
|
|
14
|
+
|
|
15
|
+
if (!existsSync(mainPath)) {
|
|
16
|
+
console.warn("⚠️ ts/main.ts not found, skipping type generation");
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const content = readFileSync(mainPath, "utf-8");
|
|
21
|
+
const globals = parseGlobalSingletons(content, mainPath);
|
|
22
|
+
|
|
23
|
+
if (globals.length === 0) {
|
|
24
|
+
console.warn("⚠️ No createGlobalSingleton calls found");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
generateDtsWithTypeChecker(globals, dtsPath, mainPath);
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
interface GlobalDeclaration {
|
|
33
|
+
name: string;
|
|
34
|
+
importPath: string;
|
|
35
|
+
exportName: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function parseGlobalSingletons(
|
|
39
|
+
content: string,
|
|
40
|
+
filePath: string
|
|
41
|
+
): GlobalDeclaration[] {
|
|
42
|
+
const sf = ts.createSourceFile(
|
|
43
|
+
filePath,
|
|
44
|
+
content,
|
|
45
|
+
ts.ScriptTarget.Latest,
|
|
46
|
+
true
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const globals: GlobalDeclaration[] = [];
|
|
50
|
+
const importMap = new Map<string, { path: string; originalName: string }>();
|
|
51
|
+
|
|
52
|
+
sf.statements.forEach((stmt) => {
|
|
53
|
+
if (ts.isImportDeclaration(stmt) && stmt.importClause) {
|
|
54
|
+
const moduleSpecifier = (stmt.moduleSpecifier as ts.StringLiteral).text;
|
|
55
|
+
|
|
56
|
+
if (stmt.importClause.namedBindings) {
|
|
57
|
+
if (ts.isNamedImports(stmt.importClause.namedBindings)) {
|
|
58
|
+
stmt.importClause.namedBindings.elements.forEach((element) => {
|
|
59
|
+
const localName = element.name.text;
|
|
60
|
+
const importedName = element.propertyName
|
|
61
|
+
? element.propertyName.text
|
|
62
|
+
: localName;
|
|
63
|
+
|
|
64
|
+
importMap.set(localName, {
|
|
65
|
+
path: moduleSpecifier,
|
|
66
|
+
originalName: importedName,
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
function visit(node: ts.Node) {
|
|
75
|
+
if (
|
|
76
|
+
ts.isCallExpression(node) &&
|
|
77
|
+
ts.isIdentifier(node.expression) &&
|
|
78
|
+
node.expression.text === "createGlobalSingleton"
|
|
79
|
+
) {
|
|
80
|
+
if (node.arguments.length >= 2) {
|
|
81
|
+
const nameArg = node.arguments[0];
|
|
82
|
+
const valueArg = node.arguments[1];
|
|
83
|
+
|
|
84
|
+
if (ts.isStringLiteral(nameArg) && ts.isIdentifier(valueArg)) {
|
|
85
|
+
const name = nameArg.text;
|
|
86
|
+
const variable = valueArg.text;
|
|
87
|
+
const importInfo = importMap.get(variable);
|
|
88
|
+
|
|
89
|
+
if (importInfo) {
|
|
90
|
+
globals.push({
|
|
91
|
+
name,
|
|
92
|
+
importPath: importInfo.path,
|
|
93
|
+
exportName: importInfo.originalName,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
ts.forEachChild(node, visit);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
visit(sf);
|
|
104
|
+
return globals;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function generateDtsWithTypeChecker(
|
|
108
|
+
globals: GlobalDeclaration[],
|
|
109
|
+
dtsPath: string,
|
|
110
|
+
mainPath: string
|
|
111
|
+
) {
|
|
112
|
+
const configPath = ts.findConfigFile(
|
|
113
|
+
process.cwd(),
|
|
114
|
+
ts.sys.fileExists,
|
|
115
|
+
"tsconfig.json"
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
const { config } = configPath
|
|
119
|
+
? ts.readConfigFile(configPath, ts.sys.readFile)
|
|
120
|
+
: { config: {} };
|
|
121
|
+
|
|
122
|
+
const { options } = ts.parseJsonConfigFileContent(
|
|
123
|
+
config,
|
|
124
|
+
ts.sys,
|
|
125
|
+
process.cwd()
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
const program = ts.createProgram([mainPath], options);
|
|
129
|
+
const checker = program.getTypeChecker();
|
|
130
|
+
const sourceFile = program.getSourceFile(mainPath);
|
|
131
|
+
|
|
132
|
+
if (!sourceFile) {
|
|
133
|
+
console.warn("⚠️ Could not load main.ts for type checking");
|
|
134
|
+
generateFallbackDts(globals, dtsPath);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const signatures = new Map<string, string>();
|
|
139
|
+
|
|
140
|
+
const importMap = new Map<string, ts.ImportDeclaration>();
|
|
141
|
+
sourceFile.statements.forEach((stmt) => {
|
|
142
|
+
if (ts.isImportDeclaration(stmt) && stmt.importClause?.namedBindings) {
|
|
143
|
+
if (ts.isNamedImports(stmt.importClause.namedBindings)) {
|
|
144
|
+
stmt.importClause.namedBindings.elements.forEach((element) => {
|
|
145
|
+
importMap.set(element.name.text, stmt);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
globals.forEach(({ name, exportName }) => {
|
|
152
|
+
try {
|
|
153
|
+
const importDecl = importMap.get(exportName);
|
|
154
|
+
if (!importDecl || !importDecl.importClause?.namedBindings) {
|
|
155
|
+
signatures.set(name, "(...args: any[]) => any");
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (ts.isNamedImports(importDecl.importClause.namedBindings)) {
|
|
160
|
+
const importSpec = importDecl.importClause.namedBindings.elements.find(
|
|
161
|
+
(el) => el.name.text === exportName
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
if (importSpec) {
|
|
165
|
+
const symbol = checker.getSymbolAtLocation(importSpec.name);
|
|
166
|
+
if (symbol) {
|
|
167
|
+
const type = checker.getTypeOfSymbolAtLocation(
|
|
168
|
+
symbol,
|
|
169
|
+
importSpec.name
|
|
170
|
+
);
|
|
171
|
+
const signature = checker.typeToString(
|
|
172
|
+
type,
|
|
173
|
+
undefined,
|
|
174
|
+
ts.TypeFormatFlags.NoTruncation
|
|
175
|
+
);
|
|
176
|
+
signatures.set(name, signature);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
signatures.set(name, "(...args: any[]) => any");
|
|
183
|
+
} catch (error) {
|
|
184
|
+
console.warn(`⚠️ Failed to extract type for ${name}:`, error);
|
|
185
|
+
signatures.set(name, "(...args: any[]) => any");
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const declarations = globals
|
|
190
|
+
.map(({ name }) => {
|
|
191
|
+
const sig = signatures.get(name) || "(...args: any[]) => any";
|
|
192
|
+
return ` const ${name}: ${sig};`;
|
|
193
|
+
})
|
|
194
|
+
.join("\n");
|
|
195
|
+
|
|
196
|
+
const windowDeclarations = globals
|
|
197
|
+
.map(({ name }) => ` ${name}: typeof globalThis.${name};`)
|
|
198
|
+
.join("\n");
|
|
199
|
+
|
|
200
|
+
const content = `// Auto-generated by Vite plugin
|
|
201
|
+
// Do not edit manually - regenerate with: npm run dev or npm run build
|
|
202
|
+
// Source: ts/main.ts
|
|
203
|
+
|
|
204
|
+
declare global {
|
|
205
|
+
${declarations}
|
|
206
|
+
|
|
207
|
+
interface Window {
|
|
208
|
+
${windowDeclarations}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export {};
|
|
213
|
+
`;
|
|
214
|
+
|
|
215
|
+
const dir = path.dirname(dtsPath);
|
|
216
|
+
if (!existsSync(dir)) {
|
|
217
|
+
mkdirSync(dir, { recursive: true });
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
writeFileSync(dtsPath, content, "utf-8");
|
|
221
|
+
console.log(`✅ Generated ${path.relative(process.cwd(), dtsPath)}`);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function generateFallbackDts(globals: GlobalDeclaration[], dtsPath: string) {
|
|
225
|
+
const declarations = globals
|
|
226
|
+
.map(({ name }) => ` const ${name}: (...args: any[]) => any;`)
|
|
227
|
+
.join("\n");
|
|
228
|
+
|
|
229
|
+
const windowDeclarations = globals
|
|
230
|
+
.map(({ name }) => ` ${name}: typeof globalThis.${name};`)
|
|
231
|
+
.join("\n");
|
|
232
|
+
|
|
233
|
+
const content = `// Auto-generated by Vite plugin
|
|
234
|
+
declare global {
|
|
235
|
+
${declarations}
|
|
236
|
+
|
|
237
|
+
interface Window {
|
|
238
|
+
${windowDeclarations}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export {};
|
|
243
|
+
`;
|
|
244
|
+
|
|
245
|
+
writeFileSync(dtsPath, content, "utf-8");
|
|
246
|
+
}
|
|
@@ -53,33 +53,20 @@ class Auth
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
|
-
* Authenticates a user and generates a JWT
|
|
57
|
-
*
|
|
58
|
-
* the token's expiration time, sets the necessary payload, and encodes it into a JWT.
|
|
59
|
-
* If possible (HTTP headers not yet sent), it also sets cookies with the JWT for client-side storage.
|
|
56
|
+
* Authenticates a user and generates a JWT.
|
|
57
|
+
* Optionally redirects the user to a default or custom URL.
|
|
60
58
|
*
|
|
61
|
-
* @param mixed $data User data
|
|
62
|
-
*
|
|
63
|
-
* @param string
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
59
|
+
* @param mixed $data User data (string or AuthRole).
|
|
60
|
+
* @param string|null $tokenValidity Duration token is valid for (e.g., '1h'). Default is '1h'.
|
|
61
|
+
* @param bool|string $redirect
|
|
62
|
+
* - If `false` (default): No redirect occurs; returns the JWT.
|
|
63
|
+
* - If `true`: Redirects to `AuthConfig::DEFAULT_SIGNIN_REDIRECT`.
|
|
64
|
+
* - If `string`: Redirects to the specified URL (e.g., '/dashboard').
|
|
67
65
|
*
|
|
68
66
|
* @return string Returns the encoded JWT as a string.
|
|
69
|
-
*
|
|
70
|
-
* @throws InvalidArgumentException Thrown if the secret key is not set or if the duration format is invalid.
|
|
71
|
-
*
|
|
72
|
-
* Example:
|
|
73
|
-
* $auth = Auth::getInstance();
|
|
74
|
-
* $auth->setSecretKey('your_secret_key');
|
|
75
|
-
* try {
|
|
76
|
-
* $jwt = $auth->signIn('Admin', '1h');
|
|
77
|
-
* echo "JWT: " . $jwt;
|
|
78
|
-
* } catch (InvalidArgumentException $e) {
|
|
79
|
-
* echo "Error: " . $e->getMessage();
|
|
80
|
-
* }
|
|
67
|
+
* @throws InvalidArgumentException
|
|
81
68
|
*/
|
|
82
|
-
public function signIn($data, ?string $tokenValidity = null): string
|
|
69
|
+
public function signIn($data, ?string $tokenValidity = null, bool|string $redirect = false): string
|
|
83
70
|
{
|
|
84
71
|
if (!$this->secretKey) {
|
|
85
72
|
throw new InvalidArgumentException("Secret key is required for authentication.");
|
|
@@ -106,6 +93,12 @@ class Auth
|
|
|
106
93
|
$this->setCookies($jwt, $expirationTime);
|
|
107
94
|
}
|
|
108
95
|
|
|
96
|
+
if ($redirect === true) {
|
|
97
|
+
Request::redirect(AuthConfig::DEFAULT_SIGNIN_REDIRECT);
|
|
98
|
+
} elseif (is_string($redirect) && !empty($redirect)) {
|
|
99
|
+
Request::redirect($redirect);
|
|
100
|
+
}
|
|
101
|
+
|
|
109
102
|
return $jwt;
|
|
110
103
|
}
|
|
111
104
|
|
package/dist/src/app/layout.php
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<?php
|
|
2
2
|
|
|
3
3
|
use PP\MainLayout;
|
|
4
|
-
use PP\Request;
|
|
5
4
|
|
|
6
5
|
MainLayout::$title = !empty(MainLayout::$title) ? MainLayout::$title : 'Create Prisma PHP App';
|
|
7
6
|
MainLayout::$description = !empty(MainLayout::$description) ? MainLayout::$description : 'Generated by create Prisma PHP App';
|
|
@@ -12,11 +11,11 @@ MainLayout::$description = !empty(MainLayout::$description) ? MainLayout::$descr
|
|
|
12
11
|
|
|
13
12
|
<head>
|
|
14
13
|
<!-- Dynamic Meta Tags -->
|
|
15
|
-
<link rel="icon" href="
|
|
14
|
+
<link rel="icon" href="/favicon.ico" type="image/x-icon" sizes="16x16" />
|
|
16
15
|
<!-- Dynamic Header Scripts -->
|
|
17
16
|
</head>
|
|
18
17
|
|
|
19
|
-
<body>
|
|
18
|
+
<body pp-spa="true" style="opacity:0;pointer-events:none;user-select:none;transition:opacity .18s ease-out;">
|
|
20
19
|
<?= MainLayout::$children; ?>
|
|
21
20
|
<!-- Dynamic Footer Scripts -->
|
|
22
21
|
</body>
|
package/dist/ts/main.ts
CHANGED
package/dist/tsconfig.json
CHANGED
|
@@ -106,6 +106,6 @@
|
|
|
106
106
|
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
|
107
107
|
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
|
108
108
|
},
|
|
109
|
-
|
|
109
|
+
"include": ["**/*.ts", ".pp/**/*.d.ts"],
|
|
110
110
|
"exclude": ["node_modules", "vendor"]
|
|
111
111
|
}
|
package/dist/vite.config.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { defineConfig, Plugin } from "vite";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import fg from "fast-glob";
|
|
4
4
|
import { writeFileSync } from "fs";
|
|
5
|
+
import { generateGlobalTypes } from "./settings/vite-plugins/generate-global-types.js";
|
|
5
6
|
|
|
6
7
|
const entries = Object.fromEntries(
|
|
7
8
|
fg.sync("ts/**/*.ts", { ignore: ["**/*.test.ts"] }).map((f) => {
|
|
@@ -10,6 +11,13 @@ const entries = Object.fromEntries(
|
|
|
10
11
|
})
|
|
11
12
|
);
|
|
12
13
|
|
|
14
|
+
const VITE_WATCH_EXCLUDE = [
|
|
15
|
+
"public/js/**",
|
|
16
|
+
"node_modules/**",
|
|
17
|
+
"vendor/**",
|
|
18
|
+
".pp/**",
|
|
19
|
+
];
|
|
20
|
+
|
|
13
21
|
function browserSyncNotify(): Plugin {
|
|
14
22
|
const flagFile = path.resolve(__dirname, ".pp", ".vite-build-complete");
|
|
15
23
|
|
|
@@ -21,16 +29,17 @@ function browserSyncNotify(): Plugin {
|
|
|
21
29
|
};
|
|
22
30
|
}
|
|
23
31
|
|
|
24
|
-
export default defineConfig({
|
|
32
|
+
export default defineConfig(({ command, mode }) => ({
|
|
25
33
|
publicDir: false,
|
|
26
34
|
build: {
|
|
27
35
|
outDir: "public/js",
|
|
28
36
|
emptyOutDir: false,
|
|
29
37
|
minify: "esbuild",
|
|
30
38
|
sourcemap: false,
|
|
31
|
-
watch:
|
|
32
|
-
|
|
33
|
-
|
|
39
|
+
watch:
|
|
40
|
+
command === "build" && mode === "development"
|
|
41
|
+
? { exclude: VITE_WATCH_EXCLUDE }
|
|
42
|
+
: undefined,
|
|
34
43
|
rollupOptions: {
|
|
35
44
|
input: entries,
|
|
36
45
|
external: [/^\/js\/.*/],
|
|
@@ -41,7 +50,12 @@ export default defineConfig({
|
|
|
41
50
|
},
|
|
42
51
|
},
|
|
43
52
|
},
|
|
44
|
-
plugins: [
|
|
53
|
+
plugins: [
|
|
54
|
+
generateGlobalTypes(),
|
|
55
|
+
...(command === "build" && mode === "development"
|
|
56
|
+
? [browserSyncNotify()]
|
|
57
|
+
: []),
|
|
58
|
+
],
|
|
45
59
|
esbuild: { legalComments: "none" },
|
|
46
60
|
define: { "process.env.NODE_ENV": '"production"' },
|
|
47
|
-
});
|
|
61
|
+
}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-prisma-php-app",
|
|
3
|
-
"version": "4.1.0
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "Prisma-PHP: A Revolutionary Library Bridging PHP with Prisma ORM",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -32,15 +32,15 @@
|
|
|
32
32
|
"author": "Jefferson Abraham Omier <thesteelninjacode@gmail.com>",
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"chalk": "^5.
|
|
35
|
+
"chalk": "^5.6.2",
|
|
36
36
|
"crypto-js": "^4.2.0",
|
|
37
37
|
"prompts": "^2.4.2"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/crypto-js": "^4.2.2",
|
|
41
|
-
"@types/node": "^
|
|
41
|
+
"@types/node": "^25.0.3",
|
|
42
42
|
"@types/prompts": "^2.4.9",
|
|
43
43
|
"ts-node": "^10.9.2",
|
|
44
|
-
"typescript": "^5.
|
|
44
|
+
"typescript": "^5.9.3"
|
|
45
45
|
}
|
|
46
46
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{L as o,T as p,a as t}from"./pp-reactive-v1.js";import"./pp-portal.js";export{o as LoopManager,p as TemplateRenderer,t as TemplateUtils};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
class m{portals=new Map;portalCounter=0;componentManager;domBindingManager;cleanupObserver;stateManager;pphpInstance;constructor(){this.cleanupObserver=new MutationObserver(e=>{this.handleMutations(e)}),this.cleanupObserver.observe(document.body,{childList:!0,subtree:!0})}setDependencies(e,t,n,r){this.componentManager=e,this.domBindingManager=t,this.stateManager=n,this.pphpInstance=r}createPortal(e,t,n){const r=typeof t=="string"?document.querySelector(t):t;if(!r)throw new Error(`Portal container not found: ${t}`);const o=this.componentManager?.getCurrentComponent()||"app",a=n?.key||`portal_${++this.portalCounter}_${Date.now()}`;this.portals.has(a)&&this.removePortal(a);const s={id:a,content:e,container:r,component:o};return this.portals.set(a,s),this.renderPortalWithHydration(s,n,a),a}async renderPortalWithHydration(e,t,n){if(!this.componentManager||!this.domBindingManager){console.warn("PortalManager dependencies not set");return}try{await this.renderPortal(e,t),await new Promise(r=>requestAnimationFrame(r)),this.domBindingManager.processPendingBindings(),await new Promise(r=>{this.stateManager?.onDOMUpdateComplete(()=>{r(void 0)})}),this.pphpInstance&&this.pphpInstance.markPortalHydrated&&this.pphpInstance.markPortalHydrated(n),t?.onMount&&t.onMount(e.container)}catch(r){console.error("Portal hydration error:",r),this.pphpInstance&&this.pphpInstance.markPortalHydrated&&this.pphpInstance.markPortalHydrated(n)}}renderPortal(e,t){return new Promise((n,r)=>{if(!this.componentManager||!this.domBindingManager){console.warn("PortalManager dependencies not set"),r(new Error("Dependencies not set"));return}try{e.renderedContent&&e.renderedContent.parentElement&&e.renderedContent.parentElement.removeChild(e.renderedContent);let o;if(typeof e.content=="string"){const s=document.createElement("template");if(s.innerHTML=e.content.trim(),o=s.content.firstElementChild,!o)throw new Error("Invalid HTML string for portal content")}else if(e.content instanceof DocumentFragment){const s=document.createElement("div");if(s.appendChild(e.content.cloneNode(!0)),o=s.firstElementChild,!o)throw new Error("DocumentFragment must contain at least one element")}else o=e.content;o.setAttribute("data-portal-id",e.id),o.setAttribute("data-portal-component",e.component),e.container.appendChild(o),e.renderedContent=o;const a=[...this.componentManager.componentStack];try{this.componentManager.executePhpScripts(o),this.domBindingManager.processElement(o,!0);const s=o.querySelectorAll("template[pp-for]"),i=this.domBindingManager.loopManager;i&&(s.forEach(d=>{const l=d;if(i.loopBindings?.has(l))if(typeof i.updateTemplateParent=="function")i.updateTemplateParent(l);else{const c=i.loopBindings.get(l);c&&(c.subscriptionIds?.forEach(p=>{this.stateManager?.removeSubscription(p)}),i.loopBindings.delete(l)),i.processTemplate(l,e.component)}else i.queueTemplate(l,e.component)}),i.processPendingTemplates()),this.domBindingManager.processPendingBindings(),n()}finally{this.componentManager.componentStack=a}}catch(o){console.error("Portal rendering error:",o),this.portals.delete(e.id),r(o)}})}removePortal(e){const t=this.portals.get(e);if(!t)return!1;try{return t.cleanup&&t.cleanup(),t.renderedContent&&this.cleanupPortalElement(t.renderedContent),t.renderedContent&&t.renderedContent.parentElement&&t.renderedContent.parentElement.removeChild(t.renderedContent),this.portals.delete(e),!0}catch(n){return console.error("Portal cleanup error:",n),!1}}cleanupPortalElement(e){if(this.stateManager){const t=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT,null);let n=e;do n.nodeType===Node.ELEMENT_NODE&&this.stateManager.subscriptionManager?.cleanupElement(n);while(n=t.nextNode())}}updatePortal(e,t,n){const r=this.portals.get(e);return r?(r.content=t,this.renderPortal(r,n),!0):!1}getPortal(e){return this.portals.get(e)}hasPortal(e){return this.portals.has(e)}getAllPortals(){return Array.from(this.portals.values())}handleMutations(e){for(const t of e)t.type==="childList"&&t.removedNodes.forEach(n=>{if(n.nodeType===Node.ELEMENT_NODE){const r=n;for(const[o,a]of this.portals)(a.container===r||r.contains(a.container))&&this.removePortal(o)}})}destroy(){for(const e of Array.from(this.portals.keys()))this.removePortal(e);this.cleanupObserver.disconnect(),this.portals.clear()}}export{m as P};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{P as ce}from"./pp-reactive-v1.js";import"./pp-portal.js";var ee=11;function le(i,e){var t=e.attributes,n,a,r,s,u;if(!(e.nodeType===ee||i.nodeType===ee)){for(var f=t.length-1;f>=0;f--)n=t[f],a=n.name,r=n.namespaceURI,s=n.value,r?(a=n.localName||a,u=i.getAttributeNS(r,a),u!==s&&(n.prefix==="xmlns"&&(a=n.name),i.setAttributeNS(r,a,s))):(u=i.getAttribute(a),u!==s&&i.setAttribute(a,s));for(var b=i.attributes,m=b.length-1;m>=0;m--)n=b[m],a=n.name,r=n.namespaceURI,r?(a=n.localName||a,e.hasAttributeNS(r,a)||i.removeAttributeNS(r,a)):e.hasAttribute(a)||i.removeAttribute(a)}}var D,de="http://www.w3.org/1999/xhtml",v=typeof document>"u"?void 0:document,ue=!!v&&"content"in v.createElement("template"),he=!!v&&v.createRange&&"createContextualFragment"in v.createRange();function fe(i){var e=v.createElement("template");return e.innerHTML=i,e.content.childNodes[0]}function pe(i){D||(D=v.createRange(),D.selectNode(v.body));var e=D.createContextualFragment(i);return e.childNodes[0]}function ve(i){var e=v.createElement("body");return e.innerHTML=i,e.childNodes[0]}function ge(i){return i=i.trim(),ue?fe(i):he?pe(i):ve(i)}function $(i,e){var t=i.nodeName,n=e.nodeName,a,r;return t===n?!0:(a=t.charCodeAt(0),r=n.charCodeAt(0),a<=90&&r>=97?t===n.toUpperCase():r<=90&&a>=97?n===t.toUpperCase():!1)}function me(i,e){return!e||e===de?v.createElement(i):v.createElementNS(e,i)}function ye(i,e){for(var t=i.firstChild;t;){var n=t.nextSibling;e.appendChild(t),t=n}return e}function j(i,e,t){i[t]!==e[t]&&(i[t]=e[t],i[t]?i.setAttribute(t,""):i.removeAttribute(t))}var te={OPTION:function(i,e){var t=i.parentNode;if(t){var n=t.nodeName.toUpperCase();n==="OPTGROUP"&&(t=t.parentNode,n=t&&t.nodeName.toUpperCase()),n==="SELECT"&&!t.hasAttribute("multiple")&&(i.hasAttribute("selected")&&!e.selected&&(i.setAttribute("selected","selected"),i.removeAttribute("selected")),t.selectedIndex=-1)}j(i,e,"selected")},INPUT:function(i,e){j(i,e,"checked"),j(i,e,"disabled"),i.value!==e.value&&(i.value=e.value),e.hasAttribute("value")||i.removeAttribute("value")},TEXTAREA:function(i,e){var t=e.value;i.value!==t&&(i.value=t);var n=i.firstChild;if(n){var a=n.nodeValue;if(a==t||!t&&a==i.placeholder)return;n.nodeValue=t}},SELECT:function(i,e){if(!e.hasAttribute("multiple")){for(var t=-1,n=0,a=i.firstChild,r,s;a;)if(s=a.nodeName&&a.nodeName.toUpperCase(),s==="OPTGROUP")r=a,a=r.firstChild,a||(a=r.nextSibling,r=null);else{if(s==="OPTION"){if(a.hasAttribute("selected")){t=n;break}n++}a=a.nextSibling,!a&&r&&(a=r.nextSibling,r=null)}i.selectedIndex=t}}},R=1,ne=11,ae=3,ie=8;function T(){}function we(i){if(i)return i.getAttribute&&i.getAttribute("id")||i.id}function be(i){return function(t,n,a){if(a||(a={}),typeof n=="string")if(t.nodeName==="#document"||t.nodeName==="HTML"||t.nodeName==="BODY"){var r=n;n=v.createElement("html"),n.innerHTML=r}else n=ge(n);else n.nodeType===ne&&(n=n.firstElementChild);var s=a.getNodeKey||we,u=a.onBeforeNodeAdded||T,f=a.onNodeAdded||T,b=a.onBeforeElUpdated||T,m=a.onElUpdated||T,I=a.onBeforeNodeDiscarded||T,g=a.onNodeDiscarded||T,y=a.onBeforeElChildrenUpdated||T,E=a.skipFromChildren||T,x=a.addChild||function(o,c){return o.appendChild(c)},q=a.childrenOnly===!0,C=Object.create(null),U=[];function _(o){U.push(o)}function X(o,c){if(o.nodeType===R)for(var h=o.firstChild;h;){var l=void 0;c&&(l=s(h))?_(l):(g(h),h.firstChild&&X(h,c)),h=h.nextSibling}}function K(o,c,h){I(o)!==!1&&(c&&c.removeChild(o),g(o),X(o,h))}function G(o){if(o.nodeType===R||o.nodeType===ne)for(var c=o.firstChild;c;){var h=s(c);h&&(C[h]=c),G(c),c=c.nextSibling}}G(t);function M(o){f(o);for(var c=o.firstChild;c;){var h=c.nextSibling,l=s(c);if(l){var d=C[l];d&&$(c,d)?(c.parentNode.replaceChild(d,c),H(d,c)):M(c)}else M(c);c=h}}function re(o,c,h){for(;c;){var l=c.nextSibling;(h=s(c))?_(h):K(c,o,!0),c=l}}function H(o,c,h){var l=s(c);if(l&&delete C[l],!h){var d=b(o,c);if(d===!1||(d instanceof HTMLElement&&(o=d,G(o)),i(o,c),m(o),y(o,c)===!1))return}o.nodeName!=="TEXTAREA"?se(o,c):te.TEXTAREA(o,c)}function se(o,c){var h=E(o,c),l=c.firstChild,d=o.firstChild,N,w,O,B,S;e:for(;l;){for(B=l.nextSibling,N=s(l);!h&&d;){if(O=d.nextSibling,l.isSameNode&&l.isSameNode(d)){l=B,d=O;continue e}w=s(d);var V=d.nodeType,A=void 0;if(V===l.nodeType&&(V===R?(N?N!==w&&((S=C[N])?O===S?A=!1:(o.insertBefore(S,d),w?_(w):K(d,o,!0),d=S,w=s(d)):A=!1):w&&(A=!1),A=A!==!1&&$(d,l),A&&H(d,l)):(V===ae||V==ie)&&(A=!0,d.nodeValue!==l.nodeValue&&(d.nodeValue=l.nodeValue))),A){l=B,d=O;continue e}w?_(w):K(d,o,!0),d=O}if(N&&(S=C[N])&&$(S,l))h||x(o,S),H(S,l);else{var W=u(l);W!==!1&&(W&&(l=W),l.actualize&&(l=l.actualize(o.ownerDocument||v)),x(o,l),M(l))}l=B,d=O}re(o,d,w);var Z=te[o.nodeName];Z&&Z(o,c)}var p=t,F=p.nodeType,Q=n.nodeType;if(!q){if(F===R)Q===R?$(t,n)||(g(t),p=ye(t,me(n.nodeName,n.namespaceURI))):p=n;else if(F===ae||F===ie){if(Q===F)return p.nodeValue!==n.nodeValue&&(p.nodeValue=n.nodeValue),p;p=n}}if(p===n)g(t);else{if(n.isSameNode&&n.isSameNode(p))return;if(H(p,n,q),U)for(var Y=0,oe=U.length;Y<oe;Y++){var J=C[U[Y]];J&&K(J,J.parentNode,!1)}}return!q&&p!==t&&t.parentNode&&(p.actualize&&(p=p.actualize(t.ownerDocument||v)),t.parentNode.replaceChild(p,t)),p}}var Se=be(le);class P extends ce{static instance=null;cryptoKey=null;activeAbortController=null;navigationEnabled=!1;boundHandleLinkClick=null;boundHandlePopState=null;isNavigating=!1;constructor(){super(),this.hydrated().then(()=>{this.isNavigating||(document.body.hidden=!1),this.enableSPANavigation()}).catch(e=>{console.error("PPHPUtilities hydration error:",e),document.body.hidden=!1})}static resetInstance(){this.instance&&(this.instance.navigationEnabled&&this.instance.disableSPANavigation(),this.instance.activeAbortController&&(this.instance.activeAbortController.abort(),this.instance.activeAbortController=null),this.instance.destroy(),this.instance=null)}static getInstance(){return this.instance||(this.instance=new P),this.instance}enableSPANavigation(){this.navigationEnabled||(this.navigationEnabled=!0,this.boundHandleLinkClick=this.handleLinkClick.bind(this),this.boundHandlePopState=this.handlePopState.bind(this),document.addEventListener("click",this.boundHandleLinkClick),window.addEventListener("popstate",this.boundHandlePopState))}disableSPANavigation(){this.navigationEnabled=!1,this.boundHandleLinkClick&&(document.removeEventListener("click",this.boundHandleLinkClick),this.boundHandleLinkClick=null),this.boundHandlePopState&&(window.removeEventListener("popstate",this.boundHandlePopState),this.boundHandlePopState=null)}handleLinkClick(e){if(!this.navigationEnabled)return;const n=e.target.closest("a");if(!(!n||!n.href))try{const a=new URL(n.href),r=a.origin!==window.location.origin,s=a.pathname===window.location.pathname&&a.search===window.location.search;if(r||n.target==="_blank"||n.hasAttribute("download")||n.getAttribute("pp-no-spa")==="true"||e.ctrlKey||e.metaKey||e.shiftKey||e.altKey)return;if(e.preventDefault(),s){const u=a.hash;if(u){const f=document.querySelector(u);f&&f.scrollIntoView({behavior:"smooth"})}else window.scrollTo({top:0,behavior:"smooth"});return}this.navigateTo(a.pathname+a.search+a.hash)}catch(a){console.error("Link click navigation error:",a)}}async handlePopState(){const e=window.location.pathname+window.location.search+window.location.hash;await this.navigateTo(e,!1)}async navigateTo(e,t=!0){this.isNavigating=!0;try{this.dispatchNavigationEvent("start",e),await this.showLoadingTransition();const n=await this.fetchPageContent(e);this.performCleanup(),this.updateBrowserHistory(e,t);const a=document.getElementById("loading-file-1B87E"),r="startViewTransition"in document;!a&&r?await this.updatePageContentWithViewTransition(n):this.updatePageContent(n),await this.reinitializeApp(),await this.handleNavigationCompletion(e),this.dispatchNavigationEvent("complete",e)}catch(n){this.handleNavigationError(e,n)}finally{this.isNavigating=!1}}async updatePageContentWithViewTransition(e){if(this.isNavigating){this.updatePageContent(e);return}const t=document.startViewTransition(()=>{this.updatePageContent(e)});try{await t.finished}catch(n){console.warn("View transition failed, continuing anyway:",n)}}dispatchNavigationEvent(e,t,n){const a=`pp:navigation:${e}`,r=n?{url:t,error:n}:{url:t};document.dispatchEvent(new CustomEvent(a,{detail:r}))}async showLoadingTransition(){const e=document.getElementById("loading-file-1B87E");if(e){const n=this.findLoadingElement(e,window.location.pathname);if(n){await this.updateContentWithTransition(n);return}}const t=document.querySelector("[pp-loading-content='true']")||document.body;t&&!("startViewTransition"in document)&&await this.fadeOut(t,250)}async fetchPageContent(e){const t=await fetch(e,{headers:{"X-Requested-With":"XMLHttpRequest",Accept:"text/html"}});if(!t.ok)throw new Error(`Navigation failed: ${t.status} ${t.statusText}`);const n=await t.text();return new DOMParser().parseFromString(n,"text/html")}performCleanup(){this.cleanup(),this.disableSPANavigation()}updateBrowserHistory(e,t){t&&history.pushState(null,"",e)}updatePageContent(e){e.title&&(document.title=e.title),this.reconcileHead(e);const t=e.body;Se(document.body,t,{childrenOnly:!0,onBeforeElUpdated:(n,a)=>!n.isEqualNode(a)})}async reinitializeApp(){window.pp=null,P.instance=null;const e=window.pp;return await e.hydrated(),e}async handleNavigationCompletion(e){const t=new URL(e,window.location.origin).hash;if(t){const a=document.querySelector(t);a&&a.scrollIntoView({behavior:"smooth"})}else window.scrollTo({top:0,behavior:"instant"});const n=document.querySelector("[pp-loading-content='true']")||document.body;n?requestAnimationFrame(()=>{document.body.hidden=!1,this.fadeIn(n,150)}):document.body.hidden=!1}handleNavigationError(e,t){console.error("Navigation error:",t),document.body.hidden=!1,this.dispatchNavigationEvent("error",e,t),window.location.href=e}findLoadingElement(e,t){let n=t;for(;;){const a=e.querySelector(`div[pp-loading-url='${n}']`);if(a)return a;if(n==="/")break;const r=n.lastIndexOf("/");r<=0?n="/":n=n.substring(0,r)}return e.querySelector("div[pp-loading-url='/' ]")}async updateContentWithTransition(e){const t=document.querySelector("[pp-loading-content='true']")||document.body;if(!t)return;const{fadeIn:n,fadeOut:a}=this.parseTransition(e);await this.fadeOut(t,a),t.innerHTML=e.innerHTML,this.fadeIn(t,n)}parseTransition(e){let t=250,n=250;const r=e.querySelector("[pp-loading-transition]")?.getAttribute("pp-loading-transition");if(r){let s=JSON.parse(r);s&&typeof s=="object"?(t=this.parseTime(s.fadeIn??t),n=this.parseTime(s.fadeOut??n)):console.warn("pp-loading-transition is not valid JSON → default values (250 ms) will be used. String:",r)}return{fadeIn:t,fadeOut:n}}fadeOut(e,t){return new Promise(n=>{e.style.transition=`opacity ${t}ms ease-out`,setTimeout(()=>{e.style.transition="",n()},t)})}fadeIn(e,t){e.style.transition=`opacity ${t}ms ease-in`,setTimeout(()=>{e.style.transition=""},t)}parseTime(e){if(typeof e=="number")return e;const t=e.match(/^(\d+)(ms|s|m)?$/);if(t){const n=parseInt(t[1],10);switch(t[2]||"ms"){case"ms":return n;case"s":return n*1e3;case"m":return n*60*1e3;default:return n}}return 0}reconcileHead(e){const t="pp-dynamic-script",n="pp-dynamic-meta",a="pp-dynamic-link";document.head.querySelectorAll(`[${n}]`).forEach(r=>r.remove()),document.head.querySelectorAll(`[${a}]`).forEach(r=>r.remove()),document.head.querySelectorAll(`[${t}]`).forEach(r=>r.remove()),Array.from(e.head.children).forEach(r=>{switch(r.tagName){case"SCRIPT":if(r.hasAttribute(t)){const s=document.createElement("script");Array.from(r.attributes).forEach(u=>s.setAttribute(u.name,u.value)),s.textContent=r.textContent,document.head.appendChild(s)}break;case"META":{const s=r;if(s.getAttribute("charset")||s.name==="viewport")break;const u=s.name?`meta[name="${s.name}"]`:`meta[property="${s.getAttribute("property")}"]`,f=s.cloneNode(!0),b=document.head.querySelector(u);b?document.head.replaceChild(f,b):document.head.insertBefore(f,document.head.querySelector("title")?.nextSibling||null);break}case"TITLE":{const s=r.cloneNode(!0),u=document.head.querySelector("title");u?document.head.replaceChild(s,u):document.head.appendChild(s);break}case"LINK":{const s=r;if(s.rel==="icon"){const u=s.cloneNode(!0),f=document.head.querySelector('link[rel="icon"]');f?document.head.replaceChild(u,f):document.head.appendChild(u)}else s.hasAttribute(a)&&document.head.appendChild(s.cloneNode(!0));break}}})}async redirect(e){if(e)try{const t=new URL(e,window.location.origin);t.origin!==window.location.origin?window.location.href=e:this.navigationEnabled?await this.navigateTo(t.pathname+t.search+t.hash):window.location.href=e}catch(t){console.error("Redirect error:",t)}}async initCryptoKey(){const e=document.cookie.split("; ").find(u=>u.startsWith("pp_function_call_jwt="))?.split("=",2)[1];if(!e)throw new Error("Missing function-call token");const[,t]=e.split("."),n=atob(t.replace(/-/g,"+").replace(/_/g,"/")),{k:a,exp:r}=JSON.parse(n);if(Date.now()/1e3>r)throw new Error("Function-call token expired");const s=Uint8Array.from(atob(a),u=>u.charCodeAt(0));this.cryptoKey=await crypto.subtle.importKey("raw",s,{name:"AES-CBC"},!1,["encrypt","decrypt"])}async encryptCallbackName(e){await this.initCryptoKey();const t=crypto.getRandomValues(new Uint8Array(16)),n=new TextEncoder().encode(e),a=await crypto.subtle.encrypt({name:"AES-CBC",iv:t},this.cryptoKey,n),r=btoa(String.fromCharCode(...t)),s=btoa(String.fromCharCode(...new Uint8Array(a)));return`${r}:${s}`}createFetchOptions(e){return{method:"POST",headers:{"Content-Type":"application/json",HTTP_PP_WIRE_REQUEST:"true"},body:JSON.stringify(e)}}async fetchFunction(e,t={},n=!1){let a=null;try{n&&this.activeAbortController&&(this.activeAbortController.abort(),this.activeAbortController=null),a=new AbortController,n&&(this.activeAbortController=a);const s={callback:await this.encryptCallbackName(e),...t},u=window.location.href;let f;if(Object.keys(s).some(g=>{const y=s[g];return y instanceof File||y instanceof FileList&&y.length>0})){const g=new FormData;Object.keys(s).forEach(y=>{const E=s[y];E instanceof File?g.append(y,E):E instanceof FileList?Array.from(E).forEach(x=>g.append(y,x)):g.append(y,E)}),f={method:"POST",headers:{HTTP_PP_WIRE_REQUEST:"true"},body:g,signal:a.signal}}else f={signal:a.signal,...this.createFetchOptions(s)};const m=await fetch(u,f);if(!m.ok)throw new Error(`Fetch failed with status: ${m.status} ${m.statusText}`);const I=await m.text();a&&this.activeAbortController===a&&(this.activeAbortController=null);try{return JSON.parse(I)}catch{return I}}catch(r){if(a&&this.activeAbortController===a&&(this.activeAbortController=null),r instanceof Error&&r.name==="AbortError")return console.log("Request was cancelled"),{cancelled:!0};throw console.error("Error in fetchFunction:",r),new Error("Failed to fetch data.")}}}class k{state;static instance=null;listeners;pp;STORAGE_KEY;lastSyncedState=null;constructor(e={}){this.state=e,this.listeners=[],this.pp=P.getInstance(),this.STORAGE_KEY=this.getCookie("pp_local_store_key")||"pp_local_store_59e13",this.lastSyncedState=localStorage.getItem(this.STORAGE_KEY),this.loadState()}static getInstance(e={}){return k.instance||(k.instance=new k(e)),k.instance}getCookie(e){return document.cookie.split("; ").find(t=>t.startsWith(e+"="))?.split("=")[1]||null}setState(e,t=!1){const n={...this.state,...e};if(JSON.stringify(n)!==JSON.stringify(this.state)&&(this.state=n,this.listeners.forEach(a=>a(this.state)),this.saveState(),t)){const a=localStorage.getItem(this.STORAGE_KEY);a&&a!==this.lastSyncedState&&(this.pp.fetchFunction(this.STORAGE_KEY,{[this.STORAGE_KEY]:a}),this.lastSyncedState=a)}}saveState(){localStorage.setItem(this.STORAGE_KEY,JSON.stringify(this.state))}loadState(){const e=localStorage.getItem(this.STORAGE_KEY);e&&(this.state=JSON.parse(e),this.listeners.forEach(t=>t(this.state)))}resetState(e,t=!1){if(e?(delete this.state[e],this.saveState()):(this.state={},localStorage.removeItem(this.STORAGE_KEY)),this.listeners.forEach(n=>n(this.state)),t){const n=e?localStorage.getItem(this.STORAGE_KEY):null;this.pp.fetchFunction(this.STORAGE_KEY,{[this.STORAGE_KEY]:n}),this.lastSyncedState=n}}}class L{static instance=null;listeners=[];constructor(){}static getInstance(){return L.instance||(L.instance=new L),L.instance}get params(){return new URLSearchParams(window.location.search)}get(e){return this.params.get(e)}set(e,t){const n=this.params;n.set(e,t),this.updateURL(n)}delete(e){const t=this.params;t.delete(e),this.updateURL(t)}replace(e){const t=new URLSearchParams;for(const n in e){const a=e[n];a!==null&&t.set(n,a)}this.updateURL(t,!0)}updateURL(e,t=!1){const n=`${window.location.pathname}?${e.toString()}`;t?history.replaceState(null,"",n):history.pushState(null,"",n),this.notifyListeners(e)}listen(e){this.listeners.push(e)}notifyListeners(e){for(const t of this.listeners)t(e)}enablePopStateListener(){window.addEventListener("popstate",()=>{this.notifyListeners(this.params)})}}function z(i,e,t=window,n=!0){let a=null;if(Object.defineProperty(t,i,{get(){if(a!==null)return a;if(e&&typeof e=="object"&&!Array.isArray(e)&&"getInstance"in e&&typeof e.getInstance=="function")return a=e.getInstance(),a;if(typeof e=="function")try{return a=e.getInstance(),a}catch{return a=e,a}else return a=e,a},set(r){r===null?a=null:console.warn(`Cannot override global ${i}`)},configurable:!0,enumerable:!0}),n)try{t[i]}catch(r){console.error(`Failed to initialize ${i}:`,r)}}z("pp",P);z("store",k);z("searchParams",L);
|
|
File without changes
|