pulse-js-framework 1.4.4 → 1.4.6
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 +74 -0
- package/cli/index.js +23 -20
- package/cli/logger.js +122 -0
- package/index.js +8 -2
- package/loader/vite-plugin.js +22 -6
- package/package.json +37 -6
- package/runtime/dom.js +55 -11
- package/runtime/hmr.js +169 -0
- package/runtime/index.js +2 -0
- package/runtime/logger.js +304 -0
- package/runtime/native.js +7 -4
- package/runtime/pulse.js +446 -62
- package/runtime/store.js +227 -19
- package/types/index.d.ts +20 -1
- package/types/logger.d.ts +122 -0
- package/types/pulse.d.ts +33 -0
package/runtime/hmr.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HMR (Hot Module Replacement) utilities for Pulse framework
|
|
3
|
+
* @module pulse-js-framework/runtime/hmr
|
|
4
|
+
*
|
|
5
|
+
* Provides state preservation and effect cleanup during hot module replacement.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* import { createHMRContext } from 'pulse-js-framework/runtime/hmr';
|
|
9
|
+
*
|
|
10
|
+
* const hmr = createHMRContext(import.meta.url);
|
|
11
|
+
*
|
|
12
|
+
* // State preserved across HMR updates
|
|
13
|
+
* const count = hmr.preservePulse('count', 0);
|
|
14
|
+
*
|
|
15
|
+
* // Effects tracked for cleanup
|
|
16
|
+
* hmr.setup(() => {
|
|
17
|
+
* effect(() => console.log(count.get()));
|
|
18
|
+
* });
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { pulse } from './pulse.js';
|
|
22
|
+
import { setCurrentModule, clearCurrentModule, disposeModule } from './pulse.js';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @typedef {Object} HMRContext
|
|
26
|
+
* @property {Object} data - Persistent data storage across HMR updates
|
|
27
|
+
* @property {function(string, *, Object=): Pulse} preservePulse - Create a pulse with preserved state
|
|
28
|
+
* @property {function(function): *} setup - Execute code with module tracking
|
|
29
|
+
* @property {function(function): void} accept - Register HMR accept callback
|
|
30
|
+
* @property {function(function): void} dispose - Register HMR dispose callback
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Create an HMR context for a module.
|
|
35
|
+
* Provides utilities for state preservation and effect cleanup during HMR.
|
|
36
|
+
*
|
|
37
|
+
* @param {string} moduleId - The module identifier (typically import.meta.url)
|
|
38
|
+
* @returns {HMRContext} HMR context with preservation utilities
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* const hmr = createHMRContext(import.meta.url);
|
|
42
|
+
*
|
|
43
|
+
* // Preserve state across HMR
|
|
44
|
+
* const todos = hmr.preservePulse('todos', []);
|
|
45
|
+
* const filter = hmr.preservePulse('filter', 'all');
|
|
46
|
+
*
|
|
47
|
+
* // Setup effects with automatic cleanup
|
|
48
|
+
* hmr.setup(() => {
|
|
49
|
+
* effect(() => {
|
|
50
|
+
* document.title = `${todos.get().length} todos`;
|
|
51
|
+
* });
|
|
52
|
+
* });
|
|
53
|
+
*
|
|
54
|
+
* // Accept HMR updates
|
|
55
|
+
* hmr.accept();
|
|
56
|
+
*/
|
|
57
|
+
export function createHMRContext(moduleId) {
|
|
58
|
+
// Check if HMR is available (Vite dev server)
|
|
59
|
+
if (typeof import.meta === 'undefined' || !import.meta.hot) {
|
|
60
|
+
return createNoopContext();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const hot = import.meta.hot;
|
|
64
|
+
|
|
65
|
+
// Initialize data storage if not present
|
|
66
|
+
if (!hot.data) {
|
|
67
|
+
hot.data = {};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
/**
|
|
72
|
+
* Persistent data storage across HMR updates.
|
|
73
|
+
* Values stored here survive module reloads.
|
|
74
|
+
*/
|
|
75
|
+
data: hot.data,
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Create a pulse with state preservation across HMR updates.
|
|
79
|
+
* If a value exists from a previous module load, it's restored.
|
|
80
|
+
*
|
|
81
|
+
* @param {string} key - Unique key for this pulse within the module
|
|
82
|
+
* @param {*} initialValue - Initial value (used on first load only)
|
|
83
|
+
* @param {Object} [options] - Pulse options (equals function, etc.)
|
|
84
|
+
* @returns {Pulse} A pulse instance with preserved state
|
|
85
|
+
*/
|
|
86
|
+
preservePulse(key, initialValue, options) {
|
|
87
|
+
const fullKey = `__pulse_${key}`;
|
|
88
|
+
|
|
89
|
+
// Check if we have a preserved value from previous load
|
|
90
|
+
if (fullKey in hot.data) {
|
|
91
|
+
const p = pulse(hot.data[fullKey], options);
|
|
92
|
+
// Register to save state on next HMR update
|
|
93
|
+
hot.dispose(() => {
|
|
94
|
+
hot.data[fullKey] = p.peek();
|
|
95
|
+
});
|
|
96
|
+
return p;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// First load - create new pulse with initial value
|
|
100
|
+
const p = pulse(initialValue, options);
|
|
101
|
+
// Register to save state on HMR update
|
|
102
|
+
hot.dispose(() => {
|
|
103
|
+
hot.data[fullKey] = p.peek();
|
|
104
|
+
});
|
|
105
|
+
return p;
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Execute code with module tracking enabled.
|
|
110
|
+
* Effects created within this callback will be registered
|
|
111
|
+
* for automatic cleanup during HMR.
|
|
112
|
+
*
|
|
113
|
+
* @param {function} callback - Code to execute with tracking
|
|
114
|
+
* @returns {*} The return value of the callback
|
|
115
|
+
*/
|
|
116
|
+
setup(callback) {
|
|
117
|
+
setCurrentModule(moduleId);
|
|
118
|
+
try {
|
|
119
|
+
return callback();
|
|
120
|
+
} finally {
|
|
121
|
+
clearCurrentModule();
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Register a callback to run when the module accepts an HMR update.
|
|
127
|
+
*
|
|
128
|
+
* @param {function} [callback] - Optional callback for custom handling
|
|
129
|
+
*/
|
|
130
|
+
accept(callback) {
|
|
131
|
+
if (callback) {
|
|
132
|
+
hot.accept(callback);
|
|
133
|
+
} else {
|
|
134
|
+
hot.accept();
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Register a callback to run before the module is replaced.
|
|
140
|
+
* Use this for custom cleanup logic.
|
|
141
|
+
*
|
|
142
|
+
* @param {function} callback - Cleanup callback
|
|
143
|
+
*/
|
|
144
|
+
dispose(callback) {
|
|
145
|
+
hot.dispose(callback);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Create a no-op HMR context for production or non-HMR environments.
|
|
152
|
+
* All methods work normally but without HMR-specific behavior.
|
|
153
|
+
*
|
|
154
|
+
* @returns {HMRContext} A no-op HMR context
|
|
155
|
+
* @private
|
|
156
|
+
*/
|
|
157
|
+
function createNoopContext() {
|
|
158
|
+
return {
|
|
159
|
+
data: {},
|
|
160
|
+
preservePulse: (key, initialValue, options) => pulse(initialValue, options),
|
|
161
|
+
setup: (callback) => callback(),
|
|
162
|
+
accept: () => {},
|
|
163
|
+
dispose: () => {}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export default {
|
|
168
|
+
createHMRContext
|
|
169
|
+
};
|
package/runtime/index.js
CHANGED
|
@@ -7,9 +7,11 @@ export * from './dom.js';
|
|
|
7
7
|
export * from './router.js';
|
|
8
8
|
export * from './store.js';
|
|
9
9
|
export * from './native.js';
|
|
10
|
+
export * from './logger.js';
|
|
10
11
|
|
|
11
12
|
export { default as PulseCore } from './pulse.js';
|
|
12
13
|
export { default as PulseDOM } from './dom.js';
|
|
13
14
|
export { default as PulseRouter } from './router.js';
|
|
14
15
|
export { default as PulseStore } from './store.js';
|
|
15
16
|
export { default as PulseNative } from './native.js';
|
|
17
|
+
export { default as PulseLogger } from './logger.js';
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pulse Logger - Centralized logging with namespaces and levels
|
|
3
|
+
* @module pulse-js-framework/runtime/logger
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* import { logger, createLogger } from './logger.js';
|
|
7
|
+
*
|
|
8
|
+
* // Default logger
|
|
9
|
+
* logger.info('Hello');
|
|
10
|
+
* logger.warn('Warning');
|
|
11
|
+
* logger.error('Error');
|
|
12
|
+
*
|
|
13
|
+
* // Namespaced logger
|
|
14
|
+
* const log = createLogger('Router');
|
|
15
|
+
* log.info('Navigating to /home'); // [Router] Navigating to /home
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Log level constants
|
|
20
|
+
* @readonly
|
|
21
|
+
* @enum {number}
|
|
22
|
+
*/
|
|
23
|
+
export const LogLevel = {
|
|
24
|
+
/** No logging */
|
|
25
|
+
SILENT: 0,
|
|
26
|
+
/** Only errors */
|
|
27
|
+
ERROR: 1,
|
|
28
|
+
/** Errors and warnings */
|
|
29
|
+
WARN: 2,
|
|
30
|
+
/** Errors, warnings, and info (default) */
|
|
31
|
+
INFO: 3,
|
|
32
|
+
/** All messages including debug */
|
|
33
|
+
DEBUG: 4
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/** @type {number} */
|
|
37
|
+
let globalLevel = LogLevel.INFO;
|
|
38
|
+
|
|
39
|
+
/** @type {LogFormatter|null} */
|
|
40
|
+
let globalFormatter = null;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @callback LogFormatter
|
|
44
|
+
* @param {'error'|'warn'|'info'|'debug'} level - The log level
|
|
45
|
+
* @param {string|null} namespace - The logger namespace
|
|
46
|
+
* @param {Array<*>} args - The arguments to log
|
|
47
|
+
* @returns {string} The formatted log message
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Set the global log level for all loggers
|
|
52
|
+
* @param {number} level - A LogLevel value (SILENT=0, ERROR=1, WARN=2, INFO=3, DEBUG=4)
|
|
53
|
+
* @returns {void}
|
|
54
|
+
* @example
|
|
55
|
+
* setLogLevel(LogLevel.DEBUG); // Enable all logging
|
|
56
|
+
* setLogLevel(LogLevel.SILENT); // Disable all logging
|
|
57
|
+
*/
|
|
58
|
+
export function setLogLevel(level) {
|
|
59
|
+
globalLevel = level;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Get the current global log level
|
|
64
|
+
* @returns {number} The current LogLevel value
|
|
65
|
+
* @example
|
|
66
|
+
* const level = getLogLevel();
|
|
67
|
+
* if (level >= LogLevel.DEBUG) {
|
|
68
|
+
* // Debug logging is enabled
|
|
69
|
+
* }
|
|
70
|
+
*/
|
|
71
|
+
export function getLogLevel() {
|
|
72
|
+
return globalLevel;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Set a custom formatter function for all loggers
|
|
77
|
+
* @param {LogFormatter|null} formatter - Custom formatter function, or null to use default
|
|
78
|
+
* @returns {void}
|
|
79
|
+
* @example
|
|
80
|
+
* setFormatter((level, namespace, args) => {
|
|
81
|
+
* const timestamp = new Date().toISOString();
|
|
82
|
+
* const prefix = namespace ? `[${namespace}]` : '';
|
|
83
|
+
* return `${timestamp} ${level.toUpperCase()} ${prefix} ${args.join(' ')}`;
|
|
84
|
+
* });
|
|
85
|
+
*/
|
|
86
|
+
export function setFormatter(formatter) {
|
|
87
|
+
globalFormatter = formatter;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Format message arguments with optional namespace prefix
|
|
92
|
+
* @private
|
|
93
|
+
* @param {string|null} namespace - The logger namespace
|
|
94
|
+
* @param {Array<*>} args - Arguments to format
|
|
95
|
+
* @returns {Array<*>} Formatted arguments array
|
|
96
|
+
*/
|
|
97
|
+
function formatArgs(namespace, args) {
|
|
98
|
+
if (!namespace) return args;
|
|
99
|
+
|
|
100
|
+
// If first arg is a string, prepend namespace
|
|
101
|
+
if (typeof args[0] === 'string') {
|
|
102
|
+
return [`[${namespace}] ${args[0]}`, ...args.slice(1)];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Otherwise, add namespace as first arg
|
|
106
|
+
return [`[${namespace}]`, ...args];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @typedef {Object} Logger
|
|
111
|
+
* @property {function(...*): void} error - Log error message
|
|
112
|
+
* @property {function(...*): void} warn - Log warning message
|
|
113
|
+
* @property {function(...*): void} info - Log info message
|
|
114
|
+
* @property {function(...*): void} debug - Log debug message
|
|
115
|
+
* @property {function(string): void} group - Start a collapsed log group
|
|
116
|
+
* @property {function(): void} groupEnd - End the current log group
|
|
117
|
+
* @property {function(number, ...*): void} log - Log with custom level
|
|
118
|
+
* @property {function(string): Logger} child - Create a child logger with sub-namespace
|
|
119
|
+
*/
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @typedef {Object} LoggerOptions
|
|
123
|
+
* @property {number} [level] - Override global level for this logger instance
|
|
124
|
+
*/
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Create a logger instance with optional namespace
|
|
128
|
+
* @param {string|null} [namespace=null] - Logger namespace (e.g., 'Router', 'Store')
|
|
129
|
+
* @param {LoggerOptions} [options={}] - Logger configuration options
|
|
130
|
+
* @returns {Logger} A logger instance with error, warn, info, debug methods
|
|
131
|
+
* @example
|
|
132
|
+
* const log = createLogger('MyComponent');
|
|
133
|
+
* log.info('Initialized'); // [MyComponent] Initialized
|
|
134
|
+
* log.error('Failed', { code: 500 }); // [MyComponent] Failed { code: 500 }
|
|
135
|
+
*
|
|
136
|
+
* // With custom level
|
|
137
|
+
* const debugLog = createLogger('Debug', { level: LogLevel.DEBUG });
|
|
138
|
+
*/
|
|
139
|
+
export function createLogger(namespace = null, options = {}) {
|
|
140
|
+
const localLevel = options.level;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Check if a message at the given level should be logged
|
|
144
|
+
* @param {number} level - The log level to check
|
|
145
|
+
* @returns {boolean} True if the message should be logged
|
|
146
|
+
*/
|
|
147
|
+
function shouldLog(level) {
|
|
148
|
+
const effectiveLevel = localLevel !== undefined ? localLevel : globalLevel;
|
|
149
|
+
return level <= effectiveLevel;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
/**
|
|
154
|
+
* Log an error message (shown unless level is SILENT)
|
|
155
|
+
* @param {...*} args - Values to log
|
|
156
|
+
* @returns {void}
|
|
157
|
+
*/
|
|
158
|
+
error(...args) {
|
|
159
|
+
if (shouldLog(LogLevel.ERROR)) {
|
|
160
|
+
if (globalFormatter) {
|
|
161
|
+
console.error(globalFormatter('error', namespace, args));
|
|
162
|
+
} else {
|
|
163
|
+
console.error(...formatArgs(namespace, args));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Log a warning message (shown at WARN level and above)
|
|
170
|
+
* @param {...*} args - Values to log
|
|
171
|
+
* @returns {void}
|
|
172
|
+
*/
|
|
173
|
+
warn(...args) {
|
|
174
|
+
if (shouldLog(LogLevel.WARN)) {
|
|
175
|
+
if (globalFormatter) {
|
|
176
|
+
console.warn(globalFormatter('warn', namespace, args));
|
|
177
|
+
} else {
|
|
178
|
+
console.warn(...formatArgs(namespace, args));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Log an info message (shown at INFO level and above)
|
|
185
|
+
* @param {...*} args - Values to log
|
|
186
|
+
* @returns {void}
|
|
187
|
+
*/
|
|
188
|
+
info(...args) {
|
|
189
|
+
if (shouldLog(LogLevel.INFO)) {
|
|
190
|
+
if (globalFormatter) {
|
|
191
|
+
console.log(globalFormatter('info', namespace, args));
|
|
192
|
+
} else {
|
|
193
|
+
console.log(...formatArgs(namespace, args));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Log a debug message (only shown at DEBUG level)
|
|
200
|
+
* @param {...*} args - Values to log
|
|
201
|
+
* @returns {void}
|
|
202
|
+
*/
|
|
203
|
+
debug(...args) {
|
|
204
|
+
if (shouldLog(LogLevel.DEBUG)) {
|
|
205
|
+
if (globalFormatter) {
|
|
206
|
+
console.log(globalFormatter('debug', namespace, args));
|
|
207
|
+
} else {
|
|
208
|
+
console.log(...formatArgs(namespace, args));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Start a collapsed log group (only shown at DEBUG level)
|
|
215
|
+
* @param {string} label - The group label
|
|
216
|
+
* @returns {void}
|
|
217
|
+
*/
|
|
218
|
+
group(label) {
|
|
219
|
+
if (shouldLog(LogLevel.DEBUG)) {
|
|
220
|
+
console.group(namespace ? `[${namespace}] ${label}` : label);
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* End the current log group
|
|
226
|
+
* @returns {void}
|
|
227
|
+
*/
|
|
228
|
+
groupEnd() {
|
|
229
|
+
if (shouldLog(LogLevel.DEBUG)) {
|
|
230
|
+
console.groupEnd();
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Log a message at a custom level
|
|
236
|
+
* @param {number} level - The LogLevel to use
|
|
237
|
+
* @param {...*} args - Values to log
|
|
238
|
+
* @returns {void}
|
|
239
|
+
*/
|
|
240
|
+
log(level, ...args) {
|
|
241
|
+
if (shouldLog(level)) {
|
|
242
|
+
const formatted = formatArgs(namespace, args);
|
|
243
|
+
switch (level) {
|
|
244
|
+
case LogLevel.ERROR:
|
|
245
|
+
console.error(...formatted);
|
|
246
|
+
break;
|
|
247
|
+
case LogLevel.WARN:
|
|
248
|
+
console.warn(...formatted);
|
|
249
|
+
break;
|
|
250
|
+
default:
|
|
251
|
+
console.log(...formatted);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Create a child logger with an additional namespace segment
|
|
258
|
+
* @param {string} childNamespace - The child namespace to append
|
|
259
|
+
* @returns {Logger} A new logger with combined namespace
|
|
260
|
+
* @example
|
|
261
|
+
* const log = createLogger('App');
|
|
262
|
+
* const routerLog = log.child('Router');
|
|
263
|
+
* routerLog.info('Navigate'); // [App:Router] Navigate
|
|
264
|
+
*/
|
|
265
|
+
child(childNamespace) {
|
|
266
|
+
const combined = namespace
|
|
267
|
+
? `${namespace}:${childNamespace}`
|
|
268
|
+
: childNamespace;
|
|
269
|
+
return createLogger(combined, options);
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Default logger instance without namespace
|
|
276
|
+
* @type {Logger}
|
|
277
|
+
* @example
|
|
278
|
+
* import { logger } from './logger.js';
|
|
279
|
+
* logger.info('Application started');
|
|
280
|
+
*/
|
|
281
|
+
export const logger = createLogger();
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Pre-configured loggers for common Pulse subsystems
|
|
285
|
+
* @type {Object.<string, Logger>}
|
|
286
|
+
* @property {Logger} pulse - Logger for core reactivity system
|
|
287
|
+
* @property {Logger} dom - Logger for DOM operations
|
|
288
|
+
* @property {Logger} router - Logger for routing
|
|
289
|
+
* @property {Logger} store - Logger for state management
|
|
290
|
+
* @property {Logger} native - Logger for native/mobile features
|
|
291
|
+
* @property {Logger} hmr - Logger for hot module replacement
|
|
292
|
+
* @property {Logger} cli - Logger for CLI tools
|
|
293
|
+
*/
|
|
294
|
+
export const loggers = {
|
|
295
|
+
pulse: createLogger('Pulse'),
|
|
296
|
+
dom: createLogger('DOM'),
|
|
297
|
+
router: createLogger('Router'),
|
|
298
|
+
store: createLogger('Store'),
|
|
299
|
+
native: createLogger('Native'),
|
|
300
|
+
hmr: createLogger('HMR'),
|
|
301
|
+
cli: createLogger('CLI')
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
export default logger;
|
package/runtime/native.js
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { pulse, effect, batch } from './pulse.js';
|
|
8
|
+
import { loggers } from './logger.js';
|
|
9
|
+
|
|
10
|
+
const log = loggers.native;
|
|
8
11
|
|
|
9
12
|
/**
|
|
10
13
|
* Check if PulseMobile bridge is available
|
|
@@ -223,8 +226,8 @@ export const NativeUI = {
|
|
|
223
226
|
if (isNativeAvailable()) {
|
|
224
227
|
return getNative().UI.showToast(message, isLong);
|
|
225
228
|
}
|
|
226
|
-
// Fallback:
|
|
227
|
-
|
|
229
|
+
// Fallback: log toast message
|
|
230
|
+
log.info('Toast:', message);
|
|
228
231
|
return Promise.resolve();
|
|
229
232
|
},
|
|
230
233
|
|
|
@@ -335,7 +338,7 @@ export function exitApp() {
|
|
|
335
338
|
if (isNativeAvailable() && getNative().isAndroid) {
|
|
336
339
|
return getNative().App.exit();
|
|
337
340
|
}
|
|
338
|
-
|
|
341
|
+
log.warn('exitApp is only available on Android');
|
|
339
342
|
return Promise.resolve();
|
|
340
343
|
}
|
|
341
344
|
|
|
@@ -346,7 +349,7 @@ export function minimizeApp() {
|
|
|
346
349
|
if (isNativeAvailable()) {
|
|
347
350
|
return getNative().App.minimize();
|
|
348
351
|
}
|
|
349
|
-
|
|
352
|
+
log.warn('minimizeApp is only available in native apps');
|
|
350
353
|
return Promise.resolve();
|
|
351
354
|
}
|
|
352
355
|
|