rollipop 1.0.0-alpha.21 → 1.0.0-alpha.23
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/CHANGELOG.md +19 -0
- package/dist/{chunk-DEq-mXcV.js → _virtual/_rolldown/runtime.js} +1 -1
- package/dist/commands.d.ts +2 -4
- package/dist/commands.js +10 -3957
- package/dist/common/code.js +21 -0
- package/dist/common/constants.js +5 -0
- package/dist/common/env.js +33 -0
- package/dist/common/logger.d.ts +34 -0
- package/dist/common/logger.js +82 -0
- package/dist/common/logo.js +54 -0
- package/dist/common/progress-bar.js +167 -0
- package/dist/common/transformer.js +13 -0
- package/dist/common/types.d.ts +10 -0
- package/dist/config/compose-override.js +18 -0
- package/dist/config/defaults.d.ts +74 -0
- package/dist/config/defaults.js +74 -0
- package/dist/config/define-config.d.ts +13 -0
- package/dist/config/define-config.js +6 -0
- package/dist/config/index.d.ts +5 -0
- package/dist/config/index.js +5 -0
- package/dist/config/load-config.d.ts +19 -0
- package/dist/config/load-config.js +73 -0
- package/dist/config/merge-config.d.ts +12 -0
- package/dist/config/merge-config.js +20 -0
- package/dist/config/types.d.ts +452 -0
- package/dist/constants.d.ts +35 -0
- package/dist/constants.js +146 -0
- package/dist/core/assets.d.ts +91 -0
- package/dist/core/assets.js +244 -0
- package/dist/core/bundler.d.ts +15 -0
- package/dist/core/bundler.js +80 -0
- package/dist/core/env.d.ts +11 -0
- package/dist/core/env.js +36 -0
- package/dist/core/fs/data.js +9 -0
- package/dist/core/fs/storage.d.ts +15 -0
- package/dist/core/fs/storage.js +31 -0
- package/dist/core/plugins/babel-plugin.d.ts +22 -0
- package/dist/core/plugins/babel-plugin.js +74 -0
- package/dist/core/plugins/context.d.ts +10 -0
- package/dist/core/plugins/context.js +24 -0
- package/dist/core/plugins/dev-server-plugin.d.ts +13 -0
- package/dist/core/plugins/dev-server-plugin.js +27 -0
- package/dist/core/plugins/index.d.ts +13 -0
- package/dist/core/plugins/index.js +18 -0
- package/dist/core/plugins/prelude-plugin.d.ts +10 -0
- package/dist/core/plugins/prelude-plugin.js +23 -0
- package/dist/core/plugins/react-native-plugin.d.ts +36 -0
- package/dist/core/plugins/react-native-plugin.js +81 -0
- package/dist/core/plugins/reporter-plugin.d.ts +11 -0
- package/dist/core/plugins/reporter-plugin.js +87 -0
- package/dist/core/plugins/shared/filters.js +5 -0
- package/dist/core/plugins/swc-plugin.d.ts +26 -0
- package/dist/core/plugins/swc-plugin.js +108 -0
- package/dist/core/plugins/types.d.ts +18 -0
- package/dist/core/plugins/utils/source.js +10 -0
- package/dist/core/plugins/utils/transform-utils.js +56 -0
- package/dist/core/rolldown.js +313 -0
- package/dist/core/settings.js +19 -0
- package/dist/core/types.d.ts +83 -0
- package/dist/filter.d.ts +1 -0
- package/dist/filter.js +2 -0
- package/dist/hmr-runtime.iife.js +5 -5
- package/dist/index.d.ts +24 -1221
- package/dist/index.js +19 -4029
- package/dist/internal/react-native.js +24 -0
- package/dist/logger.js +5 -0
- package/dist/node/cli-utils.d.ts +10 -0
- package/dist/node/cli-utils.js +28 -0
- package/dist/node/cli.d.ts +6 -0
- package/dist/node/cli.js +23 -0
- package/dist/node/commands/agent/action.js +91 -0
- package/dist/node/commands/agent/command.js +10 -0
- package/dist/node/commands/agent/index.js +2 -0
- package/dist/node/commands/bundle/action.js +33 -0
- package/dist/node/commands/bundle/command.js +96 -0
- package/dist/node/commands/bundle/index.js +2 -0
- package/dist/node/commands/start/action.js +37 -0
- package/dist/node/commands/start/command.js +93 -0
- package/dist/node/commands/start/debugger.js +79 -0
- package/dist/node/commands/start/index.js +2 -0
- package/dist/node/commands/start/setup-interactive-mode.d.ts +20 -0
- package/dist/node/commands/start/setup-interactive-mode.js +107 -0
- package/dist/node/constants.js +4 -0
- package/dist/node/logger.js +5 -0
- package/dist/node/types.d.ts +23 -0
- package/dist/node/utils.js +23 -0
- package/dist/package.js +4 -0
- package/dist/runtime.js +1 -1
- package/dist/server/bundle.d.ts +12 -0
- package/dist/server/bundle.js +55 -0
- package/dist/server/bundler-pool.d.ts +51 -0
- package/dist/server/bundler-pool.js +197 -0
- package/dist/server/common/schema.js +19 -0
- package/dist/server/constants.d.ts +6 -0
- package/dist/server/constants.js +6 -0
- package/dist/server/create-dev-server.d.ts +6 -0
- package/dist/server/create-dev-server.js +185 -0
- package/dist/server/error.js +9 -0
- package/dist/server/events/event-bus.d.ts +12 -0
- package/dist/server/events/event-bus.js +16 -0
- package/dist/server/events/types.d.ts +37 -0
- package/dist/server/events/types.js +6 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +3 -0
- package/dist/server/logger.js +33 -0
- package/dist/server/mcp/context.js +14 -0
- package/dist/server/mcp/server.js +86 -0
- package/dist/server/mcp/tools/app-log-diagnostics.js +37 -0
- package/dist/server/mcp/tools/build-diagnostics.js +97 -0
- package/dist/server/mcp/tools/build-info.js +33 -0
- package/dist/server/mcp/tools/device-diagnostics.js +52 -0
- package/dist/server/mcp/tools/index.js +277 -0
- package/dist/server/middlewares/request-logger.js +15 -0
- package/dist/server/middlewares/serve-assets.js +49 -0
- package/dist/server/middlewares/serve-bundle.js +72 -0
- package/dist/server/middlewares/sse.js +34 -0
- package/dist/server/middlewares/symbolicate.js +71 -0
- package/dist/server/sse/adapter.js +74 -0
- package/dist/server/sse/event-bus.js +26 -0
- package/dist/server/symbolicate.js +93 -0
- package/dist/server/types.d.ts +125 -0
- package/dist/server/wss/hmr-server.js +209 -0
- package/dist/server/wss/server.d.ts +9 -0
- package/dist/server/wss/server.js +70 -0
- package/dist/{runtime.d.cts → types/hmr.d.ts} +1 -12
- package/dist/types.d.ts +78 -0
- package/dist/utils/babel.js +11 -0
- package/dist/utils/build-options.js +17 -0
- package/dist/utils/bundle.js +6 -0
- package/dist/utils/config.d.ts +5 -0
- package/dist/utils/config.js +32 -0
- package/dist/utils/dev-server.js +51 -0
- package/dist/utils/env.js +7 -0
- package/dist/utils/errors.js +9 -0
- package/dist/utils/hash.js +8 -0
- package/dist/utils/id.js +28 -0
- package/dist/utils/node-resolve.js +42 -0
- package/dist/utils/promise.js +15 -0
- package/dist/utils/reporters.js +120 -0
- package/dist/utils/reset-cache.d.ts +8 -0
- package/dist/utils/reset-cache.js +25 -0
- package/dist/utils/response.js +91 -0
- package/dist/utils/run-build.d.ts +8 -0
- package/dist/utils/run-build.js +7 -0
- package/dist/utils/run-server.d.ts +6 -0
- package/dist/utils/run-server.js +20 -0
- package/dist/utils/runtime-target.js +9 -0
- package/dist/utils/serialize.js +10 -0
- package/dist/utils/server.js +6 -0
- package/dist/utils/storage.js +6 -0
- package/dist/utils/string.js +6 -0
- package/dist/utils/swc.js +10 -0
- package/dist/utils/terminal.js +86 -0
- package/dist/utils/url.js +23 -0
- package/package.json +56 -68
- package/dist/commands.cjs +0 -4008
- package/dist/commands.d.cts +0 -5
- package/dist/pluginutils.d.ts +0 -1
- package/dist/pluginutils.js +0 -2
- package/dist/runtime.cjs +0 -34
- /package/dist/{chunk-DXpK5_cz.js → chunk-DJV587Yu.js} +0 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
+
//#region src/constants.ts
|
|
3
|
+
var constants_exports = /* @__PURE__ */ __exportAll({
|
|
4
|
+
DEFAULT_ASSET_EXTENSIONS: () => DEFAULT_ASSET_EXTENSIONS,
|
|
5
|
+
DEFAULT_ASSET_REGISTRY_PATH: () => DEFAULT_ASSET_REGISTRY_PATH,
|
|
6
|
+
DEFAULT_ENV_FILE: () => DEFAULT_ENV_FILE,
|
|
7
|
+
DEFAULT_ENV_PREFIX: () => DEFAULT_ENV_PREFIX,
|
|
8
|
+
DEFAULT_HMR_CLIENT_PATH: () => DEFAULT_HMR_CLIENT_PATH,
|
|
9
|
+
DEFAULT_IMAGE_EXTENSIONS: () => DEFAULT_IMAGE_EXTENSIONS,
|
|
10
|
+
DEFAULT_REACT_NATIVE_GLOBAL_IDENTIFIERS: () => DEFAULT_REACT_NATIVE_GLOBAL_IDENTIFIERS,
|
|
11
|
+
DEFAULT_RESOLVER_ALIAS_FIELDS: () => DEFAULT_RESOLVER_ALIAS_FIELDS,
|
|
12
|
+
DEFAULT_RESOLVER_CONDITION_NAMES: () => DEFAULT_RESOLVER_CONDITION_NAMES,
|
|
13
|
+
DEFAULT_RESOLVER_MAIN_FIELDS: () => DEFAULT_RESOLVER_MAIN_FIELDS,
|
|
14
|
+
DEFAULT_RUNTIME_TARGET: () => DEFAULT_RUNTIME_TARGET,
|
|
15
|
+
DEFAULT_SOURCE_EXTENSIONS: () => DEFAULT_SOURCE_EXTENSIONS,
|
|
16
|
+
GLOBAL_IDENTIFIER: () => GLOBAL_IDENTIFIER,
|
|
17
|
+
IMAGE_EXTENSIONS: () => IMAGE_EXTENSIONS,
|
|
18
|
+
ROLLIPOP_VERSION: () => ROLLIPOP_VERSION
|
|
19
|
+
});
|
|
20
|
+
const ROLLIPOP_VERSION = "1.0.0-alpha.23";
|
|
21
|
+
const GLOBAL_IDENTIFIER = "global";
|
|
22
|
+
/**
|
|
23
|
+
* @see {@link https://github.com/facebook/metro/blob/0.81.x/docs/Configuration.md#resolvermainfields}
|
|
24
|
+
*/
|
|
25
|
+
const DEFAULT_RESOLVER_MAIN_FIELDS = [
|
|
26
|
+
"react-native",
|
|
27
|
+
"browser",
|
|
28
|
+
"main"
|
|
29
|
+
];
|
|
30
|
+
const DEFAULT_RESOLVER_ALIAS_FIELDS = [["react-native"], ["browser"]];
|
|
31
|
+
const DEFAULT_RESOLVER_CONDITION_NAMES = ["react-native"];
|
|
32
|
+
/**
|
|
33
|
+
* Unlike the Metro bundler configuration, this prioritizes resolving TypeScript and ESM first.
|
|
34
|
+
*
|
|
35
|
+
* @see {@link https://github.com/facebook/metro/blob/0.81.x/packages/metro-config/src/defaults/defaults.js}
|
|
36
|
+
* @see {@link https://github.com/facebook/metro/blob/0.81.x/packages/metro-file-map/src/workerExclusionList.js}
|
|
37
|
+
*/
|
|
38
|
+
const DEFAULT_SOURCE_EXTENSIONS = [
|
|
39
|
+
"ts",
|
|
40
|
+
"tsx",
|
|
41
|
+
"js",
|
|
42
|
+
"jsx",
|
|
43
|
+
"mjs",
|
|
44
|
+
"cjs",
|
|
45
|
+
"json"
|
|
46
|
+
];
|
|
47
|
+
const DEFAULT_IMAGE_EXTENSIONS = [
|
|
48
|
+
"bmp",
|
|
49
|
+
"gif",
|
|
50
|
+
"jpg",
|
|
51
|
+
"jpeg",
|
|
52
|
+
"png",
|
|
53
|
+
"psd",
|
|
54
|
+
"svg",
|
|
55
|
+
"webp"
|
|
56
|
+
];
|
|
57
|
+
const IMAGE_EXTENSIONS = [
|
|
58
|
+
...DEFAULT_IMAGE_EXTENSIONS,
|
|
59
|
+
"tiff",
|
|
60
|
+
"ktx"
|
|
61
|
+
];
|
|
62
|
+
const DEFAULT_ASSET_EXTENSIONS = [
|
|
63
|
+
...DEFAULT_IMAGE_EXTENSIONS,
|
|
64
|
+
"xml",
|
|
65
|
+
"m4v",
|
|
66
|
+
"mov",
|
|
67
|
+
"mp4",
|
|
68
|
+
"mpeg",
|
|
69
|
+
"mpg",
|
|
70
|
+
"webm",
|
|
71
|
+
"aac",
|
|
72
|
+
"aiff",
|
|
73
|
+
"caf",
|
|
74
|
+
"m4a",
|
|
75
|
+
"mp3",
|
|
76
|
+
"wav",
|
|
77
|
+
"html",
|
|
78
|
+
"pdf",
|
|
79
|
+
"yaml",
|
|
80
|
+
"yml",
|
|
81
|
+
"otf",
|
|
82
|
+
"ttf",
|
|
83
|
+
"zip"
|
|
84
|
+
];
|
|
85
|
+
const DEFAULT_ASSET_REGISTRY_PATH = "react-native/Libraries/Image/AssetRegistry.js";
|
|
86
|
+
const DEFAULT_HMR_CLIENT_PATH = "react-native/Libraries/Utilities/HMRClient.js";
|
|
87
|
+
const DEFAULT_REACT_NATIVE_GLOBAL_IDENTIFIERS = [
|
|
88
|
+
GLOBAL_IDENTIFIER,
|
|
89
|
+
"Promise",
|
|
90
|
+
"regeneratorRuntime",
|
|
91
|
+
"XMLHttpRequest",
|
|
92
|
+
"FormData",
|
|
93
|
+
"fetch",
|
|
94
|
+
"Headers",
|
|
95
|
+
"Request",
|
|
96
|
+
"Response",
|
|
97
|
+
"WebSocket",
|
|
98
|
+
"Blob",
|
|
99
|
+
"File",
|
|
100
|
+
"FileReader",
|
|
101
|
+
"URL",
|
|
102
|
+
"URLSearchParams",
|
|
103
|
+
"AbortController",
|
|
104
|
+
"AbortSignal",
|
|
105
|
+
"queueMicrotask",
|
|
106
|
+
"setImmediate",
|
|
107
|
+
"clearImmediate",
|
|
108
|
+
"requestIdleCallback",
|
|
109
|
+
"cancelIdleCallback",
|
|
110
|
+
"setTimeout",
|
|
111
|
+
"clearTimeout",
|
|
112
|
+
"setInterval",
|
|
113
|
+
"clearInterval",
|
|
114
|
+
"requestAnimationFrame",
|
|
115
|
+
"cancelAnimationFrame",
|
|
116
|
+
"DOMRect",
|
|
117
|
+
"DOMRectReadOnly",
|
|
118
|
+
"DOMRectList",
|
|
119
|
+
"HTMLCollection",
|
|
120
|
+
"NodeList",
|
|
121
|
+
"Node",
|
|
122
|
+
"Document",
|
|
123
|
+
"CharacterData",
|
|
124
|
+
"Text",
|
|
125
|
+
"Element",
|
|
126
|
+
"HTMLElement",
|
|
127
|
+
"IntersectionObserver",
|
|
128
|
+
"MutationObserver",
|
|
129
|
+
"MutationRecord",
|
|
130
|
+
"EventCounts",
|
|
131
|
+
"Performance",
|
|
132
|
+
"PerformanceEntry",
|
|
133
|
+
"PerformanceEventTiming",
|
|
134
|
+
"PerformanceLongTaskTiming",
|
|
135
|
+
"PerformanceMark",
|
|
136
|
+
"PerformanceMeasure",
|
|
137
|
+
"PerformanceObserver",
|
|
138
|
+
"PerformanceObserverEntryList",
|
|
139
|
+
"PerformanceResourceTiming",
|
|
140
|
+
"TaskAttributionTiming"
|
|
141
|
+
];
|
|
142
|
+
const DEFAULT_ENV_PREFIX = "ROLLIPOP_";
|
|
143
|
+
const DEFAULT_ENV_FILE = ".env";
|
|
144
|
+
const DEFAULT_RUNTIME_TARGET = "hermes-v1";
|
|
145
|
+
//#endregion
|
|
146
|
+
export { DEFAULT_ASSET_EXTENSIONS, DEFAULT_ASSET_REGISTRY_PATH, DEFAULT_ENV_FILE, DEFAULT_ENV_PREFIX, DEFAULT_HMR_CLIENT_PATH, DEFAULT_REACT_NATIVE_GLOBAL_IDENTIFIERS, DEFAULT_RESOLVER_ALIAS_FIELDS, DEFAULT_RESOLVER_CONDITION_NAMES, DEFAULT_RESOLVER_MAIN_FIELDS, DEFAULT_RUNTIME_TARGET, DEFAULT_SOURCE_EXTENSIONS, GLOBAL_IDENTIFIER, IMAGE_EXTENSIONS, ROLLIPOP_VERSION, constants_exports };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
declare namespace assets_d_exports {
|
|
2
|
+
export { AssetContext, AssetData, AssetDataFiltered, AssetDataWithoutFiles, AssetInfo, AssetScale, copyAssetsToDestination, generateAssetRegistryCode, getAssetPriority, getSuffixedPath, platformSuffixPattern, resolveAssetPath, resolveScaledAssets, stripSuffix };
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* **NOTE**: Type definitions are ported from `metro` implementation.
|
|
6
|
+
*
|
|
7
|
+
* @see https://github.com/facebook/metro/blob/0.81.x/packages/metro/src/Assets.js
|
|
8
|
+
*/
|
|
9
|
+
interface AssetContext {
|
|
10
|
+
platform: string;
|
|
11
|
+
preferNativePlatform: boolean;
|
|
12
|
+
}
|
|
13
|
+
interface AssetInfo {
|
|
14
|
+
files: string[];
|
|
15
|
+
hash: string;
|
|
16
|
+
name: string;
|
|
17
|
+
scales: number[];
|
|
18
|
+
type: string;
|
|
19
|
+
}
|
|
20
|
+
interface AssetDataWithoutFiles {
|
|
21
|
+
__packager_asset: boolean;
|
|
22
|
+
fileSystemLocation: string;
|
|
23
|
+
hash: string;
|
|
24
|
+
httpServerLocation: string;
|
|
25
|
+
name: string;
|
|
26
|
+
scales: AssetScale[];
|
|
27
|
+
type: string;
|
|
28
|
+
width?: number;
|
|
29
|
+
height?: number;
|
|
30
|
+
}
|
|
31
|
+
interface AssetDataFiltered {
|
|
32
|
+
__packager_asset: boolean;
|
|
33
|
+
hash: string;
|
|
34
|
+
httpServerLocation: string;
|
|
35
|
+
name: string;
|
|
36
|
+
scales: AssetScale[];
|
|
37
|
+
type: string;
|
|
38
|
+
width?: number;
|
|
39
|
+
height?: number;
|
|
40
|
+
}
|
|
41
|
+
interface AssetData extends AssetDataWithoutFiles {
|
|
42
|
+
id: string;
|
|
43
|
+
files: string[];
|
|
44
|
+
}
|
|
45
|
+
type AssetScale = 0.75 | 1 | 1.5 | 2 | 3;
|
|
46
|
+
interface ResolveScaledAssetsOptions {
|
|
47
|
+
projectRoot: string;
|
|
48
|
+
assetPath: string;
|
|
49
|
+
platform: string;
|
|
50
|
+
preferNativePlatform: boolean;
|
|
51
|
+
}
|
|
52
|
+
declare function resolveScaledAssets(options: ResolveScaledAssetsOptions): Promise<AssetData>;
|
|
53
|
+
declare function platformSuffixPattern(context: AssetContext): string;
|
|
54
|
+
declare function stripSuffix(assetPath: string, context: AssetContext): string;
|
|
55
|
+
declare function getAssetPriority(assetPath: string, context: AssetContext): 0 | 3 | 2 | 1;
|
|
56
|
+
interface GetSuffixedPathOptions {
|
|
57
|
+
scale?: AssetScale;
|
|
58
|
+
platform?: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* add suffix to asset path
|
|
62
|
+
*
|
|
63
|
+
* ```js
|
|
64
|
+
* // assetPath input
|
|
65
|
+
* '/path/to/assets/image.png'
|
|
66
|
+
*
|
|
67
|
+
* // `platform` suffixed
|
|
68
|
+
* '/path/to/assets/image.android.png'
|
|
69
|
+
*
|
|
70
|
+
* // `scale` suffixed
|
|
71
|
+
* '/path/to/assets/image@1x.png'
|
|
72
|
+
*
|
|
73
|
+
* // both `platform` and `scale` suffixed
|
|
74
|
+
* '/path/to/assets/image@1x.android.png'
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
declare function getSuffixedPath(assetPath: string, context: AssetContext, options: GetSuffixedPathOptions): string;
|
|
78
|
+
declare function resolveAssetPath(assetPath: string, context: AssetContext, scale: AssetScale): string;
|
|
79
|
+
interface CopyAssetsToDestinationOptions {
|
|
80
|
+
assets: AssetData[];
|
|
81
|
+
assetsDir: string;
|
|
82
|
+
platform: string;
|
|
83
|
+
preferNativePlatform: boolean;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* @see https://github.com/facebook/react-native/blob/0.83-stable/packages/community-cli-plugin/src/commands/bundle/assetPathUtils.js
|
|
87
|
+
*/
|
|
88
|
+
declare function copyAssetsToDestination(options: CopyAssetsToDestinationOptions): Promise<undefined>;
|
|
89
|
+
declare function generateAssetRegistryCode(assetRegistryPath: string, asset: AssetData): string;
|
|
90
|
+
//#endregion
|
|
91
|
+
export { assets_d_exports };
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { IMAGE_EXTENSIONS } from "../constants.js";
|
|
3
|
+
import { md5 } from "../utils/hash.js";
|
|
4
|
+
import { DEV_SERVER_ASSET_PATH } from "../server/constants.js";
|
|
5
|
+
import "../server/index.js";
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { isNotNil } from "es-toolkit";
|
|
9
|
+
import { imageSize } from "image-size";
|
|
10
|
+
//#region src/core/assets.ts
|
|
11
|
+
/**
|
|
12
|
+
* **NOTE**: Type definitions are ported from `metro` implementation.
|
|
13
|
+
*
|
|
14
|
+
* @see https://github.com/facebook/metro/blob/0.81.x/packages/metro/src/Assets.js
|
|
15
|
+
*/
|
|
16
|
+
var assets_exports = /* @__PURE__ */ __exportAll({
|
|
17
|
+
copyAssetsToDestination: () => copyAssetsToDestination,
|
|
18
|
+
generateAssetRegistryCode: () => generateAssetRegistryCode,
|
|
19
|
+
getAssetPriority: () => getAssetPriority,
|
|
20
|
+
getSuffixedPath: () => getSuffixedPath,
|
|
21
|
+
platformSuffixPattern: () => platformSuffixPattern,
|
|
22
|
+
resolveAssetPath: () => resolveAssetPath,
|
|
23
|
+
resolveScaledAssets: () => resolveScaledAssets,
|
|
24
|
+
stripSuffix: () => stripSuffix
|
|
25
|
+
});
|
|
26
|
+
const SCALE_PATTERN = "@(\\d+\\.?\\d*)x";
|
|
27
|
+
const IMAGE_ASSET_TYPES = new Set(IMAGE_EXTENSIONS);
|
|
28
|
+
/**
|
|
29
|
+
* key: platform,
|
|
30
|
+
* value: allowed scales
|
|
31
|
+
*
|
|
32
|
+
* @see https://github.com/facebook/react-native/blob/0.83-stable/packages/community-cli-plugin/src/commands/bundle/filterPlatformAssetScales.js#L11
|
|
33
|
+
*/
|
|
34
|
+
const ALLOW_SCALES = { ios: [
|
|
35
|
+
1,
|
|
36
|
+
2,
|
|
37
|
+
3
|
|
38
|
+
] };
|
|
39
|
+
/**
|
|
40
|
+
* @see https://developer.android.com/training/multiscreen/screendensities#TaskProvideAltBmp
|
|
41
|
+
*/
|
|
42
|
+
const ANDROID_ASSET_QUALIFIER = {
|
|
43
|
+
.75: "ldpi",
|
|
44
|
+
1: "mdpi",
|
|
45
|
+
1.5: "hdpi",
|
|
46
|
+
2: "xhdpi",
|
|
47
|
+
3: "xxhdpi",
|
|
48
|
+
4: "xxxhdpi"
|
|
49
|
+
};
|
|
50
|
+
async function resolveScaledAssets(options) {
|
|
51
|
+
const { projectRoot, assetPath, platform, preferNativePlatform } = options;
|
|
52
|
+
const context = {
|
|
53
|
+
platform,
|
|
54
|
+
preferNativePlatform
|
|
55
|
+
};
|
|
56
|
+
const extension = path.extname(assetPath);
|
|
57
|
+
const type = extension.substring(1);
|
|
58
|
+
const relativePath = path.relative(projectRoot, assetPath);
|
|
59
|
+
const dirname = path.dirname(assetPath);
|
|
60
|
+
const files = fs.readdirSync(dirname);
|
|
61
|
+
const stripedBasename = stripSuffix(assetPath, context);
|
|
62
|
+
const suffixPattern = platformSuffixPattern(context);
|
|
63
|
+
const assetRegExp = new RegExp(`${stripedBasename}(${SCALE_PATTERN})?(?:${suffixPattern})?${extension}$`);
|
|
64
|
+
const scaledAssets = {};
|
|
65
|
+
for (const file of files.sort((a, b) => getAssetPriority(b, context) - getAssetPriority(a, context))) {
|
|
66
|
+
const match = assetRegExp.exec(file);
|
|
67
|
+
if (match) {
|
|
68
|
+
const [, , scale = "1"] = match;
|
|
69
|
+
if (scaledAssets[scale]) continue;
|
|
70
|
+
scaledAssets[scale] = file;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (!(Object.keys(scaledAssets).length && scaledAssets[1])) throw new Error(`cannot resolve base asset of ${assetPath}`);
|
|
74
|
+
const imageData = fs.readFileSync(assetPath);
|
|
75
|
+
const dimensions = IMAGE_ASSET_TYPES.has(type) ? imageSize(imageData) : void 0;
|
|
76
|
+
const filteredScaledAssets = Object.entries(scaledAssets).map(([scale, file]) => ({
|
|
77
|
+
scale: parseFloat(scale),
|
|
78
|
+
file
|
|
79
|
+
})).filter(({ scale }) => ALLOW_SCALES[platform]?.includes(scale) ?? true).reduce((acc, { scale, file }) => {
|
|
80
|
+
acc.files.push(file);
|
|
81
|
+
acc.scales.push(scale);
|
|
82
|
+
return acc;
|
|
83
|
+
}, {
|
|
84
|
+
scales: [],
|
|
85
|
+
files: []
|
|
86
|
+
});
|
|
87
|
+
return {
|
|
88
|
+
__packager_asset: true,
|
|
89
|
+
id: assetPath,
|
|
90
|
+
name: stripedBasename.replace(extension, ""),
|
|
91
|
+
type,
|
|
92
|
+
width: dimensions?.width,
|
|
93
|
+
height: dimensions?.height,
|
|
94
|
+
files: filteredScaledAssets.files,
|
|
95
|
+
scales: filteredScaledAssets.scales,
|
|
96
|
+
fileSystemLocation: path.dirname(assetPath),
|
|
97
|
+
httpServerLocation: path.join(DEV_SERVER_ASSET_PATH, path.dirname(relativePath)),
|
|
98
|
+
hash: md5(imageData)
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function platformSuffixPattern(context) {
|
|
102
|
+
return [context.platform, context.preferNativePlatform ? "native" : null].filter(isNotNil).map((platform) => `.${platform}`).join("|");
|
|
103
|
+
}
|
|
104
|
+
function stripSuffix(assetPath, context) {
|
|
105
|
+
const basename = path.basename(assetPath);
|
|
106
|
+
const extension = path.extname(assetPath);
|
|
107
|
+
const suffixPattern = platformSuffixPattern(context);
|
|
108
|
+
return basename.replace(new RegExp(`(${SCALE_PATTERN})?(?:${suffixPattern})?${extension}$`), "");
|
|
109
|
+
}
|
|
110
|
+
function getAssetPriority(assetPath, context) {
|
|
111
|
+
const suffixPattern = platformSuffixPattern(context);
|
|
112
|
+
if (new RegExp(`${SCALE_PATTERN}(?:${suffixPattern})`).test(assetPath)) return 3;
|
|
113
|
+
else if (new RegExp(`(?:${suffixPattern})`).test(assetPath)) return 2;
|
|
114
|
+
else if (new RegExp(`${SCALE_PATTERN}`).test(assetPath)) return 1;
|
|
115
|
+
return 0;
|
|
116
|
+
}
|
|
117
|
+
function addSuffix(assetPath, context, options) {
|
|
118
|
+
const extension = path.extname(assetPath);
|
|
119
|
+
return stripSuffix(assetPath, context).concat(options?.scale ? `@${options.scale}x` : "").concat(options?.platform ? `.${options.platform}${extension}` : extension);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* add suffix to asset path
|
|
123
|
+
*
|
|
124
|
+
* ```js
|
|
125
|
+
* // assetPath input
|
|
126
|
+
* '/path/to/assets/image.png'
|
|
127
|
+
*
|
|
128
|
+
* // `platform` suffixed
|
|
129
|
+
* '/path/to/assets/image.android.png'
|
|
130
|
+
*
|
|
131
|
+
* // `scale` suffixed
|
|
132
|
+
* '/path/to/assets/image@1x.png'
|
|
133
|
+
*
|
|
134
|
+
* // both `platform` and `scale` suffixed
|
|
135
|
+
* '/path/to/assets/image@1x.android.png'
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
function getSuffixedPath(assetPath, context, options) {
|
|
139
|
+
const suffixedBasename = addSuffix(assetPath, context, {
|
|
140
|
+
scale: options?.scale,
|
|
141
|
+
platform: options?.platform
|
|
142
|
+
});
|
|
143
|
+
const dirname = path.dirname(assetPath);
|
|
144
|
+
return path.join(dirname, suffixedBasename);
|
|
145
|
+
}
|
|
146
|
+
function resolveAssetPath(assetPath, context, scale) {
|
|
147
|
+
const suffixedPaths = [
|
|
148
|
+
getSuffixedPath(assetPath, context, {
|
|
149
|
+
scale,
|
|
150
|
+
platform: context.platform
|
|
151
|
+
}),
|
|
152
|
+
context.preferNativePlatform ? getSuffixedPath(assetPath, context, {
|
|
153
|
+
scale,
|
|
154
|
+
platform: "native"
|
|
155
|
+
}) : null,
|
|
156
|
+
getSuffixedPath(assetPath, context, { scale })
|
|
157
|
+
].filter(isNotNil);
|
|
158
|
+
/**
|
|
159
|
+
* When scale is 1, filename can be suffixed or non-suffixed(`image.png`).
|
|
160
|
+
*
|
|
161
|
+
* - Suffixed
|
|
162
|
+
* - `filename.<platform>@<scale>x.ext`
|
|
163
|
+
* - `filename.<platform>.ext`
|
|
164
|
+
* - `filename@<scale>x.ext`
|
|
165
|
+
* - Non suffixed
|
|
166
|
+
* - `filename.ext`
|
|
167
|
+
*
|
|
168
|
+
* 1. Resolve non-suffixed asset first.
|
|
169
|
+
* 2. If file is not exist, resolve suffixed path.
|
|
170
|
+
*/
|
|
171
|
+
if (scale === 1) try {
|
|
172
|
+
fs.statSync(assetPath);
|
|
173
|
+
return assetPath;
|
|
174
|
+
} catch {}
|
|
175
|
+
for (const suffixedPath of suffixedPaths) try {
|
|
176
|
+
fs.statSync(suffixedPath);
|
|
177
|
+
return suffixedPath;
|
|
178
|
+
} catch {}
|
|
179
|
+
throw new Error(`cannot resolve asset path for ${assetPath}`);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* @see https://github.com/facebook/react-native/blob/0.83-stable/packages/community-cli-plugin/src/commands/bundle/assetPathUtils.js
|
|
183
|
+
*/
|
|
184
|
+
async function copyAssetsToDestination(options) {
|
|
185
|
+
const { assets, platform, assetsDir, preferNativePlatform } = options;
|
|
186
|
+
const context = {
|
|
187
|
+
platform,
|
|
188
|
+
preferNativePlatform
|
|
189
|
+
};
|
|
190
|
+
const mkdirWithAssertPath = (targetPath) => {
|
|
191
|
+
const dirname = path.dirname(targetPath);
|
|
192
|
+
fs.mkdirSync(dirname, { recursive: true });
|
|
193
|
+
};
|
|
194
|
+
return Promise.all(assets.map((asset) => {
|
|
195
|
+
return Promise.all(asset.scales.map(async (scale) => {
|
|
196
|
+
if (platform !== "android") {
|
|
197
|
+
const from = resolveAssetPath(asset.id, context, scale);
|
|
198
|
+
const to = path.join(assetsDir, getIosAssetDestinationPath(asset, scale));
|
|
199
|
+
mkdirWithAssertPath(to);
|
|
200
|
+
return fs.copyFileSync(from, to);
|
|
201
|
+
}
|
|
202
|
+
const from = resolveAssetPath(asset.id, context, scale);
|
|
203
|
+
const to = path.join(assetsDir, getAndroidAssetDestinationPath(asset, scale));
|
|
204
|
+
mkdirWithAssertPath(to);
|
|
205
|
+
fs.copyFileSync(from, to);
|
|
206
|
+
})).then(() => void 0);
|
|
207
|
+
})).then(() => void 0);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* @see https://github.com/facebook/react-native/blob/0.83-stable/packages/community-cli-plugin/src/commands/bundle/getAssetDestPathIOS.js
|
|
211
|
+
*/
|
|
212
|
+
function getIosAssetDestinationPath(asset, scale) {
|
|
213
|
+
const suffix = scale === 1 ? "" : `@${scale}x`;
|
|
214
|
+
const fileName = `${asset.name + suffix}.${asset.type}`;
|
|
215
|
+
const devServerBasePath = asset.httpServerLocation.at(0) === "/" ? asset.httpServerLocation.slice(1) : asset.httpServerLocation;
|
|
216
|
+
return path.join(devServerBasePath.replace(/\.\.\//g, "_"), fileName);
|
|
217
|
+
}
|
|
218
|
+
function getAndroidAssetDestinationPath(asset, scale) {
|
|
219
|
+
const assetQualifierSuffix = ANDROID_ASSET_QUALIFIER[scale];
|
|
220
|
+
const assetName = `${asset.httpServerLocation.at(0) === "/" ? asset.httpServerLocation.slice(1) : asset.httpServerLocation}/${asset.name}`.toLowerCase().replace(/\//g, "_").replace(/(?:[^a-z0-9_])/g, "").replace(/^assets_/, "");
|
|
221
|
+
if (!assetQualifierSuffix) throw new Error(`invalid asset qualifier: ${asset.id}`);
|
|
222
|
+
return path.join(isDrawable(asset.type) ? `drawable-${assetQualifierSuffix}` : "raw", `${assetName}.${asset.type}`);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* @see https://developer.android.com/guide/topics/resources/drawable-resource
|
|
226
|
+
*/
|
|
227
|
+
function isDrawable(type) {
|
|
228
|
+
return [
|
|
229
|
+
"gif",
|
|
230
|
+
"heic",
|
|
231
|
+
"heif",
|
|
232
|
+
"jpeg",
|
|
233
|
+
"jpg",
|
|
234
|
+
"ktx",
|
|
235
|
+
"png",
|
|
236
|
+
"webp",
|
|
237
|
+
"xml"
|
|
238
|
+
].includes(type);
|
|
239
|
+
}
|
|
240
|
+
function generateAssetRegistryCode(assetRegistryPath, asset) {
|
|
241
|
+
return `module.exports = require('${assetRegistryPath}').registerAsset(${JSON.stringify(asset)});`;
|
|
242
|
+
}
|
|
243
|
+
//#endregion
|
|
244
|
+
export { assets_exports, copyAssetsToDestination, generateAssetRegistryCode, resolveAssetPath, resolveScaledAssets };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BuildOptions, DevEngine, DevEngineOptions } from "./types.js";
|
|
2
|
+
import { ResolvedConfig } from "../config/defaults.js";
|
|
3
|
+
import * as rolldown from "@rollipop/rolldown";
|
|
4
|
+
|
|
5
|
+
//#region src/core/bundler.d.ts
|
|
6
|
+
declare class Bundler {
|
|
7
|
+
private readonly config;
|
|
8
|
+
static devEngine(config: ResolvedConfig, buildOptions: Omit<BuildOptions, 'dev' | 'outfile'>, devEngineOptions: DevEngineOptions): Promise<DevEngine>;
|
|
9
|
+
static createId(config: ResolvedConfig, buildOptions: BuildOptions): string;
|
|
10
|
+
private static createContext;
|
|
11
|
+
constructor(config: ResolvedConfig);
|
|
12
|
+
build(buildOptions: BuildOptions): Promise<rolldown.OutputChunk>;
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { Bundler };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Logo } from "../common/logo.js";
|
|
2
|
+
import { resolveBuildOptions } from "../utils/build-options.js";
|
|
3
|
+
import { createId } from "../utils/id.js";
|
|
4
|
+
import { FileStorage } from "./fs/storage.js";
|
|
5
|
+
import { getOverrideOptions, getOverrideOptionsForDevServer, resolveRolldownOptions } from "./rolldown.js";
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { invariant, merge } from "es-toolkit";
|
|
9
|
+
import * as rolldown from "@rollipop/rolldown";
|
|
10
|
+
import { dev } from "@rollipop/rolldown/experimental";
|
|
11
|
+
//#region src/core/bundler.ts
|
|
12
|
+
var Bundler = class Bundler {
|
|
13
|
+
config;
|
|
14
|
+
static async devEngine(config, buildOptions, devEngineOptions) {
|
|
15
|
+
const buildType = "serve";
|
|
16
|
+
const resolvedBuildOptions = resolveBuildOptions(config, buildOptions);
|
|
17
|
+
const context = Bundler.createContext(buildType, config, resolvedBuildOptions);
|
|
18
|
+
const { input = {}, output = {} } = await resolveRolldownOptions(context, config, resolvedBuildOptions, devEngineOptions);
|
|
19
|
+
const devServerOptions = getOverrideOptionsForDevServer(resolvedBuildOptions);
|
|
20
|
+
const devEngine = await dev(merge(input, devServerOptions.input), merge(output, devServerOptions.output), {
|
|
21
|
+
watch: config.watcher,
|
|
22
|
+
...devEngineOptions
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(devEngine, "getContext", {
|
|
25
|
+
value: () => context,
|
|
26
|
+
enumerable: true,
|
|
27
|
+
configurable: false
|
|
28
|
+
});
|
|
29
|
+
return devEngine;
|
|
30
|
+
}
|
|
31
|
+
static createId(config, buildOptions) {
|
|
32
|
+
return createId(config, buildOptions);
|
|
33
|
+
}
|
|
34
|
+
static createContext(buildType, config, buildOptions) {
|
|
35
|
+
return {
|
|
36
|
+
id: Bundler.createId(config, buildOptions),
|
|
37
|
+
root: config.root,
|
|
38
|
+
storage: FileStorage.getInstance(config.root),
|
|
39
|
+
buildType,
|
|
40
|
+
state: {
|
|
41
|
+
revision: 0,
|
|
42
|
+
latestBuildStartTime: 0
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
constructor(config) {
|
|
47
|
+
this.config = config;
|
|
48
|
+
Logo.printOnce();
|
|
49
|
+
}
|
|
50
|
+
async build(buildOptions) {
|
|
51
|
+
const buildType = "build";
|
|
52
|
+
const resolvedBuildOptions = resolveBuildOptions(this.config, buildOptions);
|
|
53
|
+
const context = Bundler.createContext(buildType, this.config, resolvedBuildOptions);
|
|
54
|
+
const sourcemap = resolvedBuildOptions.sourcemap ? true : false;
|
|
55
|
+
const { input = {}, output = {} } = await resolveRolldownOptions(context, this.config, resolvedBuildOptions);
|
|
56
|
+
const overrideOptions = getOverrideOptions();
|
|
57
|
+
const mergedInput = merge(input, overrideOptions.input);
|
|
58
|
+
const mergedOutput = merge(output, overrideOptions.output);
|
|
59
|
+
const rolldownBuildOptions = {
|
|
60
|
+
...mergedInput,
|
|
61
|
+
output: {
|
|
62
|
+
...mergedOutput,
|
|
63
|
+
sourcemap
|
|
64
|
+
},
|
|
65
|
+
write: Boolean(resolvedBuildOptions.outfile)
|
|
66
|
+
};
|
|
67
|
+
const chunk = (await rolldown.build(rolldownBuildOptions)).output[0];
|
|
68
|
+
invariant(chunk, "Bundled chunk is not found");
|
|
69
|
+
if (resolvedBuildOptions.outfile && chunk.sourcemapFileName && resolvedBuildOptions.sourcemapOutfile) {
|
|
70
|
+
const outputDir = path.dirname(resolvedBuildOptions.outfile);
|
|
71
|
+
const sourcemapDir = path.dirname(resolvedBuildOptions.sourcemapOutfile);
|
|
72
|
+
const sourcemapFile = path.join(outputDir, chunk.sourcemapFileName);
|
|
73
|
+
if (!fs.existsSync(sourcemapDir)) fs.mkdirSync(sourcemapDir, { recursive: true });
|
|
74
|
+
fs.renameSync(sourcemapFile, resolvedBuildOptions.sourcemapOutfile);
|
|
75
|
+
}
|
|
76
|
+
return chunk;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
//#endregion
|
|
80
|
+
export { Bundler };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Config } from "../config/types.js";
|
|
2
|
+
//#region src/core/env.d.ts
|
|
3
|
+
interface LoadEnvOptions {
|
|
4
|
+
envDir: string;
|
|
5
|
+
envPrefix: string;
|
|
6
|
+
envFile: string;
|
|
7
|
+
mode?: Config['mode'];
|
|
8
|
+
}
|
|
9
|
+
declare function loadEnv(options: LoadEnvOptions): Record<string, string>;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { LoadEnvOptions, loadEnv };
|
package/dist/core/env.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { logger } from "../logger.js";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { invariant, isNotNil } from "es-toolkit";
|
|
5
|
+
import dotenv from "dotenv";
|
|
6
|
+
import dotenvExpand from "dotenv-expand";
|
|
7
|
+
//#region src/core/env.ts
|
|
8
|
+
function loadEnv(options) {
|
|
9
|
+
const { envDir, envPrefix, envFile, mode } = options;
|
|
10
|
+
invariant(envPrefix.length > 0, "`envPrefix` is required");
|
|
11
|
+
invariant(envFile.length > 0, "`envFile` is required");
|
|
12
|
+
const env = {};
|
|
13
|
+
const envFilesToLoad = [
|
|
14
|
+
envFile,
|
|
15
|
+
`${envFile}.local`,
|
|
16
|
+
mode ? `${envFile}.${mode}` : null,
|
|
17
|
+
mode ? `${envFile}.${mode}.local` : null
|
|
18
|
+
].filter(isNotNil);
|
|
19
|
+
for (const file of envFilesToLoad) {
|
|
20
|
+
const envPath = path.resolve(envDir, file);
|
|
21
|
+
if (!fs.existsSync(envPath)) continue;
|
|
22
|
+
logger.trace(`Loading environment variables from ${envPath}`);
|
|
23
|
+
const parsed = dotenv.parse(fs.readFileSync(envPath, "utf-8"));
|
|
24
|
+
const expanded = dotenvExpand.expand({
|
|
25
|
+
parsed,
|
|
26
|
+
processEnv: {}
|
|
27
|
+
});
|
|
28
|
+
if (expanded.parsed) Object.entries(expanded.parsed).forEach(([key, value]) => {
|
|
29
|
+
if (key.startsWith(envPrefix)) env[key] = key in process.env ? process.env[key] : value;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
logger.trace("Loaded environment variables:", env);
|
|
33
|
+
return env;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { loadEnv };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SHARED_DATA_PATH } from "../../common/constants.js";
|
|
2
|
+
import "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
//#region src/core/fs/data.ts
|
|
5
|
+
function getSharedDataPath(basePath) {
|
|
6
|
+
return path.join(basePath, SHARED_DATA_PATH);
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { getSharedDataPath };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FileStorageData } from "../../common/types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/core/fs/storage.d.ts
|
|
4
|
+
declare class FileStorage {
|
|
5
|
+
private readonly basePath;
|
|
6
|
+
private static instance;
|
|
7
|
+
private dataFilePath;
|
|
8
|
+
private data;
|
|
9
|
+
static getInstance(basePath: string): FileStorage;
|
|
10
|
+
private constructor();
|
|
11
|
+
get(): FileStorageData;
|
|
12
|
+
set(data: Partial<FileStorageData>): void;
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { FileStorage };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { getSharedDataPath } from "./data.js";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { merge } from "es-toolkit";
|
|
5
|
+
//#region src/core/fs/storage.ts
|
|
6
|
+
const DEFAULT_DATA = { build: {} };
|
|
7
|
+
var FileStorage = class FileStorage {
|
|
8
|
+
basePath;
|
|
9
|
+
static instance = null;
|
|
10
|
+
dataFilePath;
|
|
11
|
+
data;
|
|
12
|
+
static getInstance(basePath) {
|
|
13
|
+
if (FileStorage.instance == null) FileStorage.instance = new FileStorage(basePath);
|
|
14
|
+
return FileStorage.instance;
|
|
15
|
+
}
|
|
16
|
+
constructor(basePath) {
|
|
17
|
+
this.basePath = basePath;
|
|
18
|
+
this.dataFilePath = path.join(getSharedDataPath(basePath), "rollipop.json");
|
|
19
|
+
if (fs.existsSync(this.dataFilePath)) this.data = JSON.parse(fs.readFileSync(this.dataFilePath, "utf-8"));
|
|
20
|
+
else this.data = DEFAULT_DATA;
|
|
21
|
+
}
|
|
22
|
+
get() {
|
|
23
|
+
return this.data;
|
|
24
|
+
}
|
|
25
|
+
set(data) {
|
|
26
|
+
this.data = merge(this.data, data);
|
|
27
|
+
fs.writeFileSync(this.dataFilePath, JSON.stringify(this.data, null, 2));
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
//#endregion
|
|
31
|
+
export { FileStorage };
|