@simplysm/core-browser 13.0.97 → 13.0.98
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 +222 -0
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# @simplysm/core-browser
|
|
2
|
+
|
|
3
|
+
Core module (browser) -- browser-only utilities including DOM extensions, file downloads, IndexedDB storage, and virtual file system.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @simplysm/core-browser
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Side-Effect Imports
|
|
12
|
+
|
|
13
|
+
This package includes side-effect imports that augment global prototypes when the module is loaded:
|
|
14
|
+
|
|
15
|
+
- `import "./extensions/element-ext"` -- Adds methods to `Element.prototype` (`findAll`, `findFirst`, `prependChild`, `getParents`, `findFocusableParent`, `findFirstFocusableChild`, `isOffsetElement`, `isVisible`).
|
|
16
|
+
- `import "./extensions/html-element-ext"` -- Adds methods to `HTMLElement.prototype` (`repaint`, `getRelativeOffset`, `scrollIntoViewIfNeeded`).
|
|
17
|
+
|
|
18
|
+
These side effects run automatically when you import from `@simplysm/core-browser`.
|
|
19
|
+
|
|
20
|
+
## API Overview
|
|
21
|
+
|
|
22
|
+
### Extensions -- Element
|
|
23
|
+
|
|
24
|
+
| API | Type | Description |
|
|
25
|
+
|-----|------|-------------|
|
|
26
|
+
| `ElementBounds` | interface | Element bounds info (`target`, `top`, `left`, `width`, `height`) |
|
|
27
|
+
| `copyElement` | function | Copy element content to clipboard via ClipboardEvent |
|
|
28
|
+
| `pasteToElement` | function | Paste clipboard content to element via ClipboardEvent |
|
|
29
|
+
| `getBounds` | function | Get bounds for multiple elements using IntersectionObserver |
|
|
30
|
+
| `Element.findAll` | prototype method | Find all child elements matching a CSS selector |
|
|
31
|
+
| `Element.findFirst` | prototype method | Find first element matching a CSS selector |
|
|
32
|
+
| `Element.prependChild` | prototype method | Insert element as first child |
|
|
33
|
+
| `Element.getParents` | prototype method | Get all parent elements (closest to farthest) |
|
|
34
|
+
| `Element.findFocusableParent` | prototype method | Find first focusable parent element |
|
|
35
|
+
| `Element.findFirstFocusableChild` | prototype method | Find first focusable child element |
|
|
36
|
+
| `Element.isOffsetElement` | prototype method | Check if element has offset positioning |
|
|
37
|
+
| `Element.isVisible` | prototype method | Check if element is visible on screen |
|
|
38
|
+
|
|
39
|
+
### Extensions -- HTMLElement
|
|
40
|
+
|
|
41
|
+
| API | Type | Description |
|
|
42
|
+
|-----|------|-------------|
|
|
43
|
+
| `HTMLElement.repaint` | prototype method | Force repaint (triggers reflow) |
|
|
44
|
+
| `HTMLElement.getRelativeOffset` | prototype method | Calculate position relative to a parent element |
|
|
45
|
+
| `HTMLElement.scrollIntoViewIfNeeded` | prototype method | Scroll to make target visible if obscured |
|
|
46
|
+
|
|
47
|
+
### Utils
|
|
48
|
+
|
|
49
|
+
| API | Type | Description |
|
|
50
|
+
|-----|------|-------------|
|
|
51
|
+
| `downloadBlob` | function | Download a Blob as a file |
|
|
52
|
+
| `DownloadProgress` | interface | Download progress info (`receivedLength`, `contentLength`) |
|
|
53
|
+
| `fetchUrlBytes` | function | Download binary data from URL with progress callback |
|
|
54
|
+
| `openFileDialog` | function | Programmatically open file selection dialog |
|
|
55
|
+
| `StoreConfig` | interface | IndexedDB store configuration (`name`, `keyPath`) |
|
|
56
|
+
| `IndexedDbStore` | class | IndexedDB wrapper for key-value storage |
|
|
57
|
+
| `VirtualFsEntry` | interface | Virtual file system entry (`kind`, `dataBase64`) |
|
|
58
|
+
| `IndexedDbVirtualFs` | class | IndexedDB-backed virtual file system |
|
|
59
|
+
|
|
60
|
+
## `ElementBounds`
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
interface ElementBounds {
|
|
64
|
+
target: Element;
|
|
65
|
+
top: number;
|
|
66
|
+
left: number;
|
|
67
|
+
width: number;
|
|
68
|
+
height: number;
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## `copyElement`
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
function copyElement(event: ClipboardEvent): void;
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Copy element content to clipboard. Use as a copy event handler.
|
|
79
|
+
|
|
80
|
+
## `pasteToElement`
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
function pasteToElement(event: ClipboardEvent): void;
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Paste clipboard content to element. Finds the first `input`/`textarea` within the target and replaces its value.
|
|
87
|
+
|
|
88
|
+
## `getBounds`
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
async function getBounds(els: Element[], timeout?: number): Promise<ElementBounds[]>;
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Get bounds information for elements using IntersectionObserver. Throws `TimeoutError` if no response within `timeout` ms (default: 5000).
|
|
95
|
+
|
|
96
|
+
## `downloadBlob`
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
function downloadBlob(blob: Blob, fileName: string): void;
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Download a Blob as a file by creating a temporary object URL and clicking a link.
|
|
103
|
+
|
|
104
|
+
## `DownloadProgress`
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
interface DownloadProgress {
|
|
108
|
+
receivedLength: number;
|
|
109
|
+
contentLength: number;
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## `fetchUrlBytes`
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
async function fetchUrlBytes(
|
|
117
|
+
url: string,
|
|
118
|
+
options?: { onProgress?: (progress: DownloadProgress) => void },
|
|
119
|
+
): Promise<Uint8Array>;
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Download binary data from URL with optional progress callback. Pre-allocates memory when Content-Length is known.
|
|
123
|
+
|
|
124
|
+
## `openFileDialog`
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
function openFileDialog(options?: {
|
|
128
|
+
accept?: string;
|
|
129
|
+
multiple?: boolean;
|
|
130
|
+
}): Promise<File[] | undefined>;
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Programmatically open a file selection dialog. Returns `undefined` if cancelled.
|
|
134
|
+
|
|
135
|
+
## `StoreConfig`
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
interface StoreConfig {
|
|
139
|
+
name: string;
|
|
140
|
+
keyPath: string;
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## `IndexedDbStore`
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
class IndexedDbStore {
|
|
148
|
+
constructor(dbName: string, dbVersion: number, storeConfigs: StoreConfig[]);
|
|
149
|
+
async open(): Promise<IDBDatabase>;
|
|
150
|
+
async withStore<TResult>(
|
|
151
|
+
storeName: string,
|
|
152
|
+
mode: IDBTransactionMode,
|
|
153
|
+
fn: (store: IDBObjectStore) => Promise<TResult>,
|
|
154
|
+
): Promise<TResult>;
|
|
155
|
+
async get<TValue>(storeName: string, key: IDBValidKey): Promise<TValue | undefined>;
|
|
156
|
+
async put(storeName: string, value: unknown): Promise<void>;
|
|
157
|
+
async delete(storeName: string, key: IDBValidKey): Promise<void>;
|
|
158
|
+
async getAll<TItem>(storeName: string): Promise<TItem[]>;
|
|
159
|
+
close(): void;
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
IndexedDB wrapper that manages database connections, schema upgrades, and transactional CRUD operations.
|
|
164
|
+
|
|
165
|
+
## `VirtualFsEntry`
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
interface VirtualFsEntry {
|
|
169
|
+
kind: "file" | "dir";
|
|
170
|
+
dataBase64?: string;
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## `IndexedDbVirtualFs`
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
class IndexedDbVirtualFs {
|
|
178
|
+
constructor(db: IndexedDbStore, storeName: string, keyField: string);
|
|
179
|
+
async getEntry(fullKey: string): Promise<VirtualFsEntry | undefined>;
|
|
180
|
+
async putEntry(fullKey: string, kind: "file" | "dir", dataBase64?: string): Promise<void>;
|
|
181
|
+
async deleteByPrefix(keyPrefix: string): Promise<boolean>;
|
|
182
|
+
async listChildren(prefix: string): Promise<{ name: string; isDirectory: boolean }[]>;
|
|
183
|
+
async ensureDir(fullKeyBuilder: (path: string) => string, dirPath: string): Promise<void>;
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Virtual file system backed by IndexedDB. Stores files and directories as key-value entries with hierarchical path support.
|
|
188
|
+
|
|
189
|
+
## Usage Examples
|
|
190
|
+
|
|
191
|
+
### Download a file
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
import { downloadBlob } from "@simplysm/core-browser";
|
|
195
|
+
|
|
196
|
+
const blob = new Blob(["Hello"], { type: "text/plain" });
|
|
197
|
+
downloadBlob(blob, "hello.txt");
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Open file dialog and read files
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
import { openFileDialog } from "@simplysm/core-browser";
|
|
204
|
+
|
|
205
|
+
const files = await openFileDialog({ accept: ".csv", multiple: true });
|
|
206
|
+
if (files) {
|
|
207
|
+
for (const file of files) {
|
|
208
|
+
const text = await file.text();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Use IndexedDB store
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
import { IndexedDbStore } from "@simplysm/core-browser";
|
|
217
|
+
|
|
218
|
+
const store = new IndexedDbStore("myApp", 1, [{ name: "settings", keyPath: "key" }]);
|
|
219
|
+
await store.put("settings", { key: "theme", value: "dark" });
|
|
220
|
+
const item = await store.get<{ key: string; value: string }>("settings", "theme");
|
|
221
|
+
store.close();
|
|
222
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/core-browser",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.98",
|
|
4
4
|
"description": "Simplysm package - Core module (browser)",
|
|
5
5
|
"author": "simplysm",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"tabbable": "^6.4.0",
|
|
27
|
-
"@simplysm/core-common": "13.0.
|
|
27
|
+
"@simplysm/core-common": "13.0.98"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"happy-dom": "^20.8.4"
|