catalyst-core 0.0.2-canary.0 → 0.0.3-canary.1
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/README.md +18 -120
- package/babel.config.json +1 -0
- package/bin/catalyst.js +84 -14
- package/changelog.md +31 -13
- package/dist/native/androidProject/app/build.gradle.kts +180 -0
- package/dist/native/androidProject/app/proguard-rules.pro +21 -0
- package/dist/native/androidProject/app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.kt +24 -0
- package/dist/native/androidProject/app/src/main/AndroidManifest.xml +28 -0
- package/dist/native/androidProject/app/src/main/java/com/example/myapplication/MainActivity.kt +278 -0
- package/dist/native/androidProject/app/src/main/java/com/example/myapplication/WebCacheManager.kt +331 -0
- package/dist/native/androidProject/app/src/main/res/drawable/ic_launcher_background.xml +170 -0
- package/dist/native/androidProject/app/src/main/res/drawable/ic_launcher_foreground.xml +30 -0
- package/dist/native/androidProject/app/src/main/res/layout/activity_main.xml +22 -0
- package/dist/native/androidProject/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +6 -0
- package/dist/native/androidProject/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +6 -0
- package/dist/native/androidProject/app/src/main/res/mipmap-hdpi/ic_launcher.webp +0 -0
- package/dist/native/androidProject/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 -0
- package/dist/native/androidProject/app/src/main/res/mipmap-mdpi/ic_launcher.webp +0 -0
- package/dist/native/androidProject/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 -0
- package/dist/native/androidProject/app/src/main/res/mipmap-xhdpi/ic_launcher.webp +0 -0
- package/dist/native/androidProject/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 -0
- package/dist/native/androidProject/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp +0 -0
- package/dist/native/androidProject/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 -0
- package/dist/native/androidProject/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +0 -0
- package/dist/native/androidProject/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 -0
- package/dist/native/androidProject/app/src/main/res/values/colors.xml +10 -0
- package/dist/native/androidProject/app/src/main/res/values/strings.xml +3 -0
- package/dist/native/androidProject/app/src/main/res/values/themes.xml +15 -0
- package/dist/native/androidProject/app/src/main/res/values-night/themes.xml +15 -0
- package/dist/native/androidProject/app/src/main/res/xml/backup_rules.xml +13 -0
- package/dist/native/androidProject/app/src/main/res/xml/data_extraction_rules.xml +19 -0
- package/dist/native/androidProject/app/src/test/java/com/example/myapplication/ExampleUnitTest.kt +17 -0
- package/dist/native/androidProject/build.gradle.kts +5 -0
- package/dist/native/androidProject/gradle/libs.versions.toml +26 -0
- package/dist/native/androidProject/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/dist/native/androidProject/gradle/wrapper/gradle-wrapper.properties +6 -0
- package/dist/native/androidProject/gradle.properties +23 -0
- package/dist/native/androidProject/gradlew +185 -0
- package/dist/native/androidProject/gradlew.bat +89 -0
- package/dist/native/androidProject/settings.gradle.kts +35 -0
- package/dist/native/androidSetup.js +7 -0
- package/dist/native/build.swift +31 -0
- package/dist/native/buildAppAndroid.js +8 -0
- package/dist/native/buildAppIos.js +44 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/Assets.xcassets/AppIcon.appiconset/Contents.json +13 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/Assets.xcassets/Contents.json +6 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/CacheManager.swift +255 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/ContentView.swift +41 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/Info.plist +13 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/Preview Content/Preview Assets.xcassets/Contents.json +6 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/ResourceURLProtocol.swift +118 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/WebView.swift +79 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/WebViewModel.swift +47 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/WebViewNavigationDelegate.swift +140 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/iosnativeWebViewApp.swift +17 -0
- package/dist/native/iosnativeWebView/iosnativeWebView.xcodeproj/project.pbxproj +601 -0
- package/dist/native/iosnativeWebView/iosnativeWebView.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/dist/native/iosnativeWebView/iosnativeWebView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/dist/native/iosnativeWebView/iosnativeWebView.xcodeproj/xcshareddata/xcschemes/iosnativeWebView.xcscheme +112 -0
- package/dist/native/setupEmulatorIos.js +19 -0
- package/dist/native/terminalProgress.js +11 -0
- package/dist/native/utils.js +13 -0
- package/dist/scripts/loadScriptsBeforeServerStarts.js +2 -2
- package/dist/server/renderer/document/Body.js +3 -4
- package/dist/server/renderer/document/Head.js +2 -1
- package/dist/server/renderer/extract.js +27 -0
- package/dist/server/renderer/handler.js +10 -9
- package/dist/server/startServer.js +3 -3
- package/dist/webpack/babel-plugins/remove-ssr.plugin.js +1 -1
- package/dist/webpack/babel.config.client.js +1 -1
- package/dist/webpack/babel.config.ssr.js +1 -1
- package/dist/webpack/base.babel.js +3 -3
- package/dist/webpack/development.client.babel.js +1 -1
- package/dist/webpack/production.client.babel.js +2 -2
- package/dist/webpack/scssParams.js +2 -2
- package/package.json +13 -4
- package/caching.js +0 -1
- package/dist/server/renderer/extractor.js +0 -1
- package/dist/webpack/babel-plugins/chunk-group.js +0 -1
- package/index.js +0 -1
- package/logger.js +0 -10
- package/router/ClientRouter.js +0 -3
- package/router/ServerRouter.js +0 -1
- package/router.js +0 -1
- package/run.sh +0 -4
- package/scripts/build.js +0 -10
- package/scripts/checkVersion.js +0 -1
- package/scripts/devBuild.js +0 -10
- package/scripts/devServe.js +0 -5
- package/scripts/loadEnvironmentVariables.js +0 -5
- package/scripts/loadScriptsBeforeServerStarts.js +0 -5
- package/scripts/scriptUtils.js +0 -2
- package/scripts/serve.js +0 -5
- package/scripts/start.js +0 -6
- package/scripts/validator.js +0 -1
- package/server/expressServer.js +0 -9
- package/server/renderer/document/Body.js +0 -14
- package/server/renderer/document/Head.js +0 -9
- package/server/renderer/document/index.js +0 -1
- package/server/renderer/extract.js +0 -21
- package/server/renderer/handler.js +0 -17
- package/server/renderer/index.js +0 -1
- package/server/renderer/render.js +0 -21
- package/server/startServer.js +0 -6
- package/server/utils/userAgentUtil.js +0 -9
- package/server/utils/validator.js +0 -1
- package/webpack/babel-plugins/extract-fetchers.js +0 -31
- package/webpack/babel-plugins/remove-client.plugin.js +0 -5
- package/webpack/babel-plugins/remove-ssr.plugin.js +0 -5
- package/webpack/babel.config.client.js +0 -1
- package/webpack/babel.config.ssr.js +0 -1
- package/webpack/base.babel.js +0 -8
- package/webpack/development.client.babel.js +0 -4
- package/webpack/production.client.babel.js +0 -4
- package/webpack/production.ssr.babel.js +0 -4
- package/webpack/scssParams.js +0 -9
package/README.md
CHANGED
|
@@ -1,146 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://onemg.gumlet.io/staging/7ee66dfb-b5fb-4fbe-8dea-789685e45f7a.svg">
|
|
4
|
+
<img alt="Catalyst logo" src="https://onemg.gumlet.io/staging/2fdb0975-8f51-4fd1-bd7d-6375d793f581.svg" height="128">
|
|
5
|
+
</picture>
|
|
6
|
+
</div>
|
|
4
7
|
|
|
5
8
|
## Table of Contents
|
|
6
9
|
|
|
7
10
|
- Overview
|
|
8
11
|
- Installation
|
|
9
|
-
|
|
10
|
-
- serverFetcher
|
|
11
|
-
- clientFetcher
|
|
12
|
-
- refetch (for data revalidation)
|
|
13
|
-
- State Management
|
|
14
|
-
|
|
12
|
+
|
|
15
13
|
## Overview
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
Catalyst offers a comprehensive suite of features designed for modern web development. It includes isomorphic rendering for optimal performance, an extendable server with full-stack capabilities, and configurable state management. The framework employs smart prefetching of data and chunks, allows easy configuration of global styles and layouts, and provides SEO optimization at both global and page levels.
|
|
16
|
+
|
|
17
|
+
This version adds support for Universal app for both Android and iOS. Please checkout [Universal App Documentaion](https://catalyst.1mg.com/public_docs/content/Universal%20App/RunUniversalApp)
|
|
18
|
+
|
|
18
19
|
|
|
19
20
|
## Installation
|
|
20
21
|
|
|
21
22
|
**System Requirements**
|
|
22
23
|
|
|
23
24
|
- Node version 20.4.0 or later
|
|
24
|
-
- macOS and Linux
|
|
25
|
+
- Compatible with **macOS** and **Linux**
|
|
25
26
|
|
|
26
27
|
**Automatic Installation**
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
Run the following commands in the directory where you want to set up the Catalyst app:
|
|
29
30
|
|
|
30
|
-
```
|
|
31
|
+
```bash
|
|
31
32
|
npx create-catalyst-app@latest
|
|
32
33
|
```
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
- Enter the name of your Catalyst application.
|
|
37
|
-
- Choose state management.
|
|
38
|
-
- Once packages are installed,start the development server by running the following command.
|
|
35
|
+
You will see some prompts to configure your application.
|
|
39
36
|
|
|
40
|
-
```
|
|
41
|
-
cd project
|
|
37
|
+
```bash
|
|
38
|
+
cd <name-of-your-project> && npm run start
|
|
42
39
|
```
|
|
43
40
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
The dev server should be running now.
|
|
47
|
-
|
|
48
|
-
Visit our official documentation:
|
|
49
|
-
https://catalyst.1mg.com/public_docs/content/installation
|
|
50
|
-
|
|
51
|
-
## Data Fetching with Catalyst
|
|
52
|
-
|
|
53
|
-
we have serverFetcher function for fetching with SSR and clientFetcher function for fetching during client side rendering and navigations.
|
|
54
|
-
|
|
55
|
-
**serverFetcher**
|
|
56
|
-
|
|
57
|
-
server fetcher will get request, request params, search params and store (if project is setup with redux or rtk) as arguments. We can declare it as an async function and use await for fetching or use then chaining for data fetching.
|
|
58
|
-
|
|
59
|
-
if server fetcher is called for a route then client fetcher will not be called for that route, unless called with refetch.
|
|
60
|
-
|
|
61
|
-
```js
|
|
62
|
-
Home.serverFetcher = async ({ req, params, searchParams }, { store }) => {
|
|
63
|
-
store.dispatch(someAction())
|
|
64
|
-
const res = await fetch("some_url")
|
|
65
|
-
const json = await res.json()
|
|
66
|
-
return json
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
data returned from fetcher function will be accessible through useCurrentRouteData() hook provided by router.
|
|
71
|
-
|
|
72
|
-
```js
|
|
73
|
-
const [data, error, isFetched] = useCurrentRouteData()
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
error and loading state would be handled by router.
|
|
77
|
-
|
|
78
|
-
**clientFetcher**
|
|
79
|
-
|
|
80
|
-
client fetcher would be called on client side rendering and client side navigations. `store` would be available as a param in client side for dispatching redux/rtk actions.
|
|
81
|
-
|
|
82
|
-
```js
|
|
83
|
-
Home.clientFetcher = async ({ route, location, params, searchParams, navigate }, { store }) => {
|
|
84
|
-
store.dispatch(someAction())
|
|
85
|
-
const res = await fetch("some_url")
|
|
86
|
-
const json = await res.json()
|
|
87
|
-
return json
|
|
88
|
-
}
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
data returned from client fetcher function will be accessible through useCurrentRouteData() hook provided by router (hook for data access through client is same).
|
|
92
|
-
|
|
93
|
-
```js
|
|
94
|
-
const [data, error, isFetched] = useCurrentRouteData()
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
**refetch (for data revalidation)**
|
|
98
|
-
|
|
99
|
-
refetch function can be used were we need to execute clientFetcher based on some condition(such as for infinite scroll or some state change inside container or onClick.)
|
|
100
|
-
|
|
101
|
-
We can pass arguments in refetch function which would
|
|
102
|
-
|
|
103
|
-
```js
|
|
104
|
-
const [data,error,isFetched,refetch] = useCurrentRouteData()
|
|
105
|
-
|
|
106
|
-
useEffect(()=>{
|
|
107
|
-
refetch({refetchArgument:some_value})
|
|
108
|
-
},[arg])
|
|
109
|
-
|
|
110
|
-
clientFetcher = ({},{refetchArgument}) => {
|
|
111
|
-
|
|
112
|
-
const res = await api_call // refetchArg can be used as a param in api call
|
|
113
|
-
return res
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
## State Management
|
|
119
|
-
|
|
120
|
-
state management wrappers are defined in stateProvider.js file
|
|
121
|
-
|
|
122
|
-
store can be configured by manipulating store/index.js as per user requirements (custom middlewares etc can be added in this way.
|
|
123
|
-
|
|
124
|
-
initial state and request object would be provided in createStore function which will be called on server and client, we use the params to add additional arguments and middlewares in redux store.
|
|
125
|
-
|
|
126
|
-
```js
|
|
127
|
-
const configureStore = (initialState, cookies, requestObj, customHeaders) => {
|
|
128
|
-
const api = fetchInstance
|
|
129
|
-
const store = createStore({
|
|
130
|
-
reducer: rootReducer,
|
|
131
|
-
middleware: (getDefaultMiddleware) =>
|
|
132
|
-
getDefaultMiddleware({
|
|
133
|
-
thunk: {
|
|
134
|
-
extraArgument: { api },
|
|
135
|
-
},
|
|
136
|
-
}),
|
|
137
|
-
preloadedState: initialState,
|
|
138
|
-
})
|
|
139
|
-
return store
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export default configureStore
|
|
143
|
-
```
|
|
41
|
+
The development server will start at ```http://localhost:3005```
|
|
144
42
|
|
|
145
43
|
## Documentation
|
|
146
44
|
|
package/babel.config.json
CHANGED
package/bin/catalyst.js
CHANGED
|
@@ -5,34 +5,104 @@ process.on("unhandledRejection", (err) => {
|
|
|
5
5
|
})
|
|
6
6
|
const { spawnSync } = require("node:child_process")
|
|
7
7
|
const args = process.argv.slice(2)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
|
|
9
|
+
// Array of valid commands
|
|
10
|
+
const validCommands = [
|
|
11
|
+
"build", "start", "serve", "devBuild", "devServe",
|
|
12
|
+
"buildApp", "buildApp:ios", "buildApp:android",
|
|
13
|
+
"setupEmulator", "setupEmulator:ios", "setupEmulator:android"
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
// Map of platform-specific commands to their script paths
|
|
17
|
+
const platformScripts = {
|
|
18
|
+
"setupEmulator:ios": "../dist/native/setupEmulatorIos.js",
|
|
19
|
+
"setupEmulator:android": "../dist/native/androidSetup.js",
|
|
20
|
+
"buildApp:ios": "../dist/native/buildAppIos.js",
|
|
21
|
+
"buildApp:android": "../dist/native/buildAppAndroid.js"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Helper to check if arg is a platform command
|
|
25
|
+
const isPlatformCommand = (arg, prefix) => {
|
|
26
|
+
if (!arg.startsWith(`${prefix}:`)) return false
|
|
27
|
+
const platform = arg.split(':')[1]
|
|
28
|
+
return ['ios', 'android'].includes(platform) || platform === undefined
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
// Helper function to run a platform command
|
|
33
|
+
const runPlatformCommand = (baseCommand, platform) => {
|
|
34
|
+
const command = `${baseCommand}:${platform}`
|
|
14
35
|
const result = spawnSync(
|
|
15
36
|
process.execPath,
|
|
16
|
-
nodeArgs.concat(require.resolve(
|
|
37
|
+
nodeArgs.concat(require.resolve(platformScripts[command])).concat(args.slice(scriptIndex + 1)),
|
|
17
38
|
{ stdio: "inherit" }
|
|
18
39
|
)
|
|
40
|
+
return result
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Helper function to run commands for all platforms
|
|
44
|
+
const runAllPlatforms = (baseCommand) => {
|
|
45
|
+
const platforms = ['ios', 'android']
|
|
46
|
+
for (const platform of platforms) {
|
|
47
|
+
const result = runPlatformCommand(baseCommand, platform)
|
|
48
|
+
if (result.status !== 0) {
|
|
49
|
+
handleProcessResult(result)
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
process.exit(0)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const scriptIndex = args.findIndex(
|
|
57
|
+
(x) => x === "build" || x === "start" || x === "serve" || x === "devBuild" || x === "devServe" ||
|
|
58
|
+
isPlatformCommand(x, 'buildApp') || isPlatformCommand(x, 'setupEmulator')
|
|
59
|
+
)
|
|
60
|
+
const script = scriptIndex === -1 ? args[0] : args[scriptIndex]
|
|
61
|
+
const nodeArgs = scriptIndex > 0 ? args.slice(0, scriptIndex) : []
|
|
62
|
+
|
|
63
|
+
if (validCommands.includes(script)) {
|
|
64
|
+
// Handle platform-specific or combined commands
|
|
65
|
+
if (script === "buildApp" || script === "setupEmulator") {
|
|
66
|
+
// Run for all platforms if no specific platform is specified
|
|
67
|
+
runAllPlatforms(script)
|
|
68
|
+
} else if (script in platformScripts) {
|
|
69
|
+
// Run for specific platform
|
|
70
|
+
const result = spawnSync(
|
|
71
|
+
process.execPath,
|
|
72
|
+
nodeArgs.concat(require.resolve(platformScripts[script])).concat(args.slice(scriptIndex + 1)),
|
|
73
|
+
{ stdio: "inherit" }
|
|
74
|
+
)
|
|
75
|
+
handleProcessResult(result)
|
|
76
|
+
} else {
|
|
77
|
+
// Original commands
|
|
78
|
+
const result = spawnSync(
|
|
79
|
+
process.execPath,
|
|
80
|
+
nodeArgs.concat(require.resolve("../dist/scripts/" + script)).concat(args.slice(scriptIndex + 1)),
|
|
81
|
+
{ stdio: "inherit" }
|
|
82
|
+
)
|
|
83
|
+
handleProcessResult(result)
|
|
84
|
+
}
|
|
85
|
+
} else {
|
|
86
|
+
console.log('Unknown script "' + script + '".')
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Helper function to handle process results
|
|
90
|
+
function handleProcessResult(result) {
|
|
19
91
|
if (result.signal) {
|
|
20
92
|
if (result.signal === "SIGKILL") {
|
|
21
93
|
console.log(
|
|
22
94
|
"The build failed because the process exited too early. " +
|
|
23
|
-
|
|
24
|
-
|
|
95
|
+
"This probably means the system ran out of memory or someone called " +
|
|
96
|
+
"`kill -9` on the process."
|
|
25
97
|
)
|
|
26
98
|
} else if (result.signal === "SIGTERM") {
|
|
27
99
|
console.log(
|
|
28
100
|
"The build failed because the process exited too early. " +
|
|
29
|
-
|
|
30
|
-
|
|
101
|
+
"Someone might have called `kill` or `killall`, or the system could " +
|
|
102
|
+
"be shutting down."
|
|
31
103
|
)
|
|
32
104
|
}
|
|
33
105
|
process.exit(1)
|
|
34
106
|
}
|
|
35
107
|
process.exit(result.status)
|
|
36
|
-
}
|
|
37
|
-
console.log('Unknown script "' + script + '".')
|
|
38
|
-
}
|
|
108
|
+
}
|
package/changelog.md
CHANGED
|
@@ -1,18 +1,36 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [0.0.
|
|
3
|
+
## [0.0.3-canary.1] - 31-01-2025
|
|
4
4
|
|
|
5
5
|
### Changes
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
# Native WebView Implementation and Cache Management Updates
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
This PR introduces native WebView implementations for both Android and iOS platforms, along with significant cache management improvements and bug fixes.
|
|
11
|
+
|
|
12
|
+
## Changes
|
|
13
|
+
|
|
14
|
+
### New Features
|
|
15
|
+
- Implemented native Android WebView with cache management functionality
|
|
16
|
+
- Added iOS native WebView implementation with custom cache handling
|
|
17
|
+
- Introduced new cache pattern management system
|
|
18
|
+
|
|
19
|
+
### Technical Implementation Details
|
|
20
|
+
- Android:
|
|
21
|
+
- Added complete Android project structure with WebView implementation
|
|
22
|
+
- Implemented `WebCacheManager.kt` for handling cache operations
|
|
23
|
+
- Set up Gradle configuration and project dependencies
|
|
24
|
+
|
|
25
|
+
- iOS:
|
|
26
|
+
- Created iOS native WebView project with Swift
|
|
27
|
+
- Implemented `CacheManager.swift` and `ResourceURLProtocol.swift` for cache handling
|
|
28
|
+
- Added WebView navigation and view model components
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Other Changes
|
|
32
|
+
- Enhanced terminal progress reporting
|
|
33
|
+
- Updated documentation and README
|
|
34
|
+
|
|
35
|
+
## Version
|
|
36
|
+
- Target version: 0.0.3-canary.1
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import java.net.NetworkInterface
|
|
2
|
+
import java.io.File
|
|
3
|
+
import java.util.Properties
|
|
4
|
+
|
|
5
|
+
val configPath: String? by project.properties
|
|
6
|
+
|
|
7
|
+
fun getLocalIpAddress(): String {
|
|
8
|
+
return NetworkInterface.getNetworkInterfaces().toList()
|
|
9
|
+
.flatMap { it.inetAddresses.toList() }
|
|
10
|
+
.filter { !it.isLoopbackAddress && it.hostAddress.indexOf(':') == -1 }
|
|
11
|
+
.map { it.hostAddress }
|
|
12
|
+
.firstOrNull() ?: "127.0.0.1"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
plugins {
|
|
16
|
+
alias(libs.plugins.android.application)
|
|
17
|
+
alias(libs.plugins.jetbrains.kotlin.android)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
android {
|
|
21
|
+
namespace = "com.example.androidProject"
|
|
22
|
+
compileSdk = 34
|
|
23
|
+
|
|
24
|
+
defaultConfig {
|
|
25
|
+
applicationId = "com.example.androidProject"
|
|
26
|
+
minSdk = 24
|
|
27
|
+
targetSdk = 34
|
|
28
|
+
versionCode = 1
|
|
29
|
+
versionName = "1.0"
|
|
30
|
+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
|
31
|
+
buildConfigField("String", "LOCAL_IP", "\"${getLocalIpAddress()}\"")
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
buildTypes {
|
|
35
|
+
debug {
|
|
36
|
+
manifestPlaceholders += mapOf("allowCleartextTraffic" to true)
|
|
37
|
+
isMinifyEnabled = false
|
|
38
|
+
buildConfigField("Boolean", "ALLOW_MIXED_CONTENT", "true")
|
|
39
|
+
buildConfigField("String", "LOCAL_IP", "\"${getLocalIpAddress()}\"")
|
|
40
|
+
}
|
|
41
|
+
release {
|
|
42
|
+
manifestPlaceholders += mapOf("allowCleartextTraffic" to false)
|
|
43
|
+
isMinifyEnabled = false
|
|
44
|
+
proguardFiles(
|
|
45
|
+
getDefaultProguardFile("proguard-android-optimize.txt"),
|
|
46
|
+
"proguard-rules.pro"
|
|
47
|
+
)
|
|
48
|
+
buildConfigField("Boolean", "ALLOW_MIXED_CONTENT", "false")
|
|
49
|
+
buildConfigField("String", "LOCAL_IP", "\"127.0.0.1\"")
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
compileOptions {
|
|
54
|
+
sourceCompatibility = JavaVersion.VERSION_1_8
|
|
55
|
+
targetCompatibility = JavaVersion.VERSION_1_8
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
kotlinOptions {
|
|
59
|
+
jvmTarget = "1.8"
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
buildFeatures {
|
|
63
|
+
viewBinding = true
|
|
64
|
+
buildConfig = true
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
dependencies {
|
|
69
|
+
implementation(libs.androidx.core.ktx)
|
|
70
|
+
implementation(libs.androidx.appcompat)
|
|
71
|
+
implementation(libs.material)
|
|
72
|
+
implementation(libs.androidx.constraintlayout)
|
|
73
|
+
testImplementation(libs.junit)
|
|
74
|
+
androidTestImplementation(libs.androidx.junit)
|
|
75
|
+
androidTestImplementation(libs.androidx.espresso.core)
|
|
76
|
+
implementation("androidx.webkit:webkit:1.12.1")
|
|
77
|
+
implementation("org.json:json:20231013")
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Task to verify local IP
|
|
81
|
+
tasks.register("printLocalIp") {
|
|
82
|
+
doLast {
|
|
83
|
+
println("Local IP Address: ${getLocalIpAddress()}")
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
tasks.register("updateSdkPath") {
|
|
88
|
+
doLast {
|
|
89
|
+
val sdkPath: String? by project.properties
|
|
90
|
+
|
|
91
|
+
if (sdkPath == null) {
|
|
92
|
+
throw GradleException(
|
|
93
|
+
"""
|
|
94
|
+
SDK path not provided!
|
|
95
|
+
Please provide the SDK path using -PsdkPath=/path/to/sdk
|
|
96
|
+
Example: ./gradlew updateSdkPath -PsdkPath=/path/to/android/sdk
|
|
97
|
+
""".trimIndent()
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
val localProperties = File(project.rootDir, "local.properties")
|
|
102
|
+
val properties = Properties()
|
|
103
|
+
|
|
104
|
+
if (localProperties.exists()) {
|
|
105
|
+
properties.load(localProperties.inputStream())
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
properties.setProperty("sdk.dir", sdkPath)
|
|
109
|
+
properties.store(localProperties.outputStream(), "Updated SDK Path")
|
|
110
|
+
|
|
111
|
+
println("Updated SDK path to: $sdkPath")
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Task to generate WebView config
|
|
116
|
+
tasks.register("generateWebViewConfig") {
|
|
117
|
+
doLast {
|
|
118
|
+
val configJsonPath = configPath ?: throw GradleException(
|
|
119
|
+
"""
|
|
120
|
+
Config path not provided!
|
|
121
|
+
Please provide the config path using -PconfigPath=/path/to/your/config.json
|
|
122
|
+
Example: ./gradlew generateWebViewConfig -PconfigPath=/path/to/your/config.json
|
|
123
|
+
""".trimIndent()
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
val configJsonFile = File(configJsonPath)
|
|
127
|
+
if (!configJsonFile.exists()) {
|
|
128
|
+
throw GradleException("Config file not found at: $configJsonPath")
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
val configContent = configJsonFile.readText()
|
|
132
|
+
|
|
133
|
+
// Extract WEBVIEW_CONFIG section
|
|
134
|
+
val webviewConfigRegex = """"WEBVIEW_CONFIG"\s*:\s*\{([^}]*)\}""".toRegex()
|
|
135
|
+
val webviewConfigMatch = webviewConfigRegex.find(configContent)
|
|
136
|
+
val webviewConfigContent = webviewConfigMatch?.groupValues?.get(1)
|
|
137
|
+
|
|
138
|
+
val properties = Properties()
|
|
139
|
+
properties.setProperty("LOCAL_IP", getLocalIpAddress())
|
|
140
|
+
|
|
141
|
+
// Parse top-level properties
|
|
142
|
+
val topLevelRegex = """"([^"]+)"\s*:\s*"([^"]+)"""".toRegex()
|
|
143
|
+
webviewConfigContent?.let {
|
|
144
|
+
topLevelRegex.findAll(it).forEach { matchResult ->
|
|
145
|
+
val (key, value) = matchResult.destructured
|
|
146
|
+
if (key != "android") {
|
|
147
|
+
properties.setProperty(key, value)
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Parse android object specifically
|
|
153
|
+
val androidRegex = """"android"\s*:\s*\{([^}]*)\}""".toRegex()
|
|
154
|
+
val androidMatch = androidRegex.find(webviewConfigContent ?: "")
|
|
155
|
+
val androidContent = androidMatch?.groupValues?.get(1)
|
|
156
|
+
|
|
157
|
+
// Parse android object properties
|
|
158
|
+
val androidPropsRegex = """"([^"]+)"\s*:\s*"([^"]+)"""".toRegex()
|
|
159
|
+
androidContent?.let {
|
|
160
|
+
androidPropsRegex.findAll(it).forEach { matchResult ->
|
|
161
|
+
val (key, value) = matchResult.destructured
|
|
162
|
+
properties.setProperty("android.$key", value)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Create the assets directory if it doesn't exist
|
|
167
|
+
val assetsDir = File("${project.projectDir}/src/main/assets")
|
|
168
|
+
if (!assetsDir.exists()) {
|
|
169
|
+
assetsDir.mkdirs()
|
|
170
|
+
println("Created assets directory at ${assetsDir.absolutePath}")
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Write to properties file
|
|
174
|
+
File(assetsDir, "webview_config.properties").outputStream().use {
|
|
175
|
+
properties.store(it, "WebView Configuration")
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
println("WebView config generated at ${assetsDir.absolutePath}/webview_config.properties")
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Add project specific ProGuard rules here.
|
|
2
|
+
# You can control the set of applied configuration files using the
|
|
3
|
+
# proguardFiles setting in build.gradle.
|
|
4
|
+
#
|
|
5
|
+
# For more details, see
|
|
6
|
+
# http://developer.android.com/guide/developing/tools/proguard.html
|
|
7
|
+
|
|
8
|
+
# If your project uses WebView with JS, uncomment the following
|
|
9
|
+
# and specify the fully qualified class name to the JavaScript interface
|
|
10
|
+
# class:
|
|
11
|
+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
|
12
|
+
# public *;
|
|
13
|
+
#}
|
|
14
|
+
|
|
15
|
+
# Uncomment this to preserve the line number information for
|
|
16
|
+
# debugging stack traces.
|
|
17
|
+
#-keepattributes SourceFile,LineNumberTable
|
|
18
|
+
|
|
19
|
+
# If you keep the line number information, uncomment this to
|
|
20
|
+
# hide the original source file name.
|
|
21
|
+
#-renamesourcefileattribute SourceFile
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
package com.example.myapplication
|
|
2
|
+
|
|
3
|
+
import androidx.test.platform.app.InstrumentationRegistry
|
|
4
|
+
import androidx.test.ext.junit.runners.AndroidJUnit4
|
|
5
|
+
|
|
6
|
+
import org.junit.Test
|
|
7
|
+
import org.junit.runner.RunWith
|
|
8
|
+
|
|
9
|
+
import org.junit.Assert.*
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Instrumented test, which will execute on an Android device.
|
|
13
|
+
*
|
|
14
|
+
* See [testing documentation](http://d.android.com/tools/testing).
|
|
15
|
+
*/
|
|
16
|
+
@RunWith(AndroidJUnit4::class)
|
|
17
|
+
class ExampleInstrumentedTest {
|
|
18
|
+
@Test
|
|
19
|
+
fun useAppContext() {
|
|
20
|
+
// Context of the app under test.
|
|
21
|
+
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
|
22
|
+
assertEquals("com.example.myapplication", appContext.packageName)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
3
|
+
xmlns:tools="http://schemas.android.com/tools">
|
|
4
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
|
5
|
+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
6
|
+
<application
|
|
7
|
+
android:usesCleartextTraffic="${allowCleartextTraffic}"
|
|
8
|
+
android:allowBackup="true"
|
|
9
|
+
android:dataExtractionRules="@xml/data_extraction_rules"
|
|
10
|
+
android:fullBackupContent="@xml/backup_rules"
|
|
11
|
+
android:icon="@mipmap/ic_launcher"
|
|
12
|
+
android:label="@string/app_name"
|
|
13
|
+
android:roundIcon="@mipmap/ic_launcher_round"
|
|
14
|
+
android:supportsRtl="true"
|
|
15
|
+
android:theme="@style/Theme.AndroidProject"
|
|
16
|
+
tools:targetApi="31">
|
|
17
|
+
<activity
|
|
18
|
+
android:name=".MainActivity"
|
|
19
|
+
android:exported="true">
|
|
20
|
+
<intent-filter>
|
|
21
|
+
<action android:name="android.intent.action.MAIN" />
|
|
22
|
+
|
|
23
|
+
<category android:name="android.intent.category.LAUNCHER" />
|
|
24
|
+
</intent-filter>
|
|
25
|
+
</activity>
|
|
26
|
+
</application>
|
|
27
|
+
|
|
28
|
+
</manifest>
|