@simplysm/core-browser 14.0.1 → 14.0.4
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 +224 -0
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# @simplysm/core-browser
|
|
2
|
+
|
|
3
|
+
Core browser utilities -- DOM extensions, file operations, IndexedDB wrappers.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @simplysm/core-browser
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## API
|
|
12
|
+
|
|
13
|
+
### Extensions
|
|
14
|
+
|
|
15
|
+
| Export | Kind | Description |
|
|
16
|
+
|--------|------|-------------|
|
|
17
|
+
| `ElementBounds` | interface | Element bounding rectangle data |
|
|
18
|
+
| Element prototype extensions | side-effect import | DOM query/traversal helpers added to `Element.prototype` |
|
|
19
|
+
| HTMLElement prototype extensions | side-effect import | Repaint, relative offset, scroll helpers added to `HTMLElement.prototype` |
|
|
20
|
+
| `copyElement` | function | Copy element content to clipboard |
|
|
21
|
+
| `pasteToElement` | function | Paste clipboard content to element |
|
|
22
|
+
| `getBounds` | async function | Get element bounds via IntersectionObserver |
|
|
23
|
+
|
|
24
|
+
### Utils
|
|
25
|
+
|
|
26
|
+
| Export | Kind | Description |
|
|
27
|
+
|--------|------|-------------|
|
|
28
|
+
| `downloadBlob` | function | Download a Blob as a file |
|
|
29
|
+
| `DownloadProgress` | interface | Progress info for byte fetching |
|
|
30
|
+
| `fetchUrlBytes` | async function | Fetch URL content as `Uint8Array` with progress |
|
|
31
|
+
| `openFileDialog` | function | Open a native file picker dialog |
|
|
32
|
+
| `StoreConfig` | interface | IndexedDB store configuration |
|
|
33
|
+
| `IndexedDbStore` | class | IndexedDB key-value store wrapper |
|
|
34
|
+
| `VirtualFsEntry` | interface | Virtual filesystem entry descriptor |
|
|
35
|
+
| `IndexedDbVirtualFs` | class | Virtual filesystem backed by IndexedDB |
|
|
36
|
+
|
|
37
|
+
## Extensions
|
|
38
|
+
|
|
39
|
+
### ElementBounds (interface)
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
interface ElementBounds {
|
|
43
|
+
target: Element;
|
|
44
|
+
top: number;
|
|
45
|
+
left: number;
|
|
46
|
+
width: number;
|
|
47
|
+
height: number;
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Element prototype extensions (side-effect import)
|
|
52
|
+
|
|
53
|
+
Import `@simplysm/core-browser` to activate these extensions on `Element.prototype`.
|
|
54
|
+
|
|
55
|
+
| Method | Signature | Description |
|
|
56
|
+
|--------|-----------|-------------|
|
|
57
|
+
| `findAll` | `findAll<TEl>(selector: string): TEl[]` | Find all matching descendants |
|
|
58
|
+
| `findFirst` | `findFirst<TEl>(selector: string): TEl \| undefined` | Find first matching descendant |
|
|
59
|
+
| `prependChild` | `prependChild<TEl>(child: TEl): TEl` | Prepend a child element |
|
|
60
|
+
| `getParents` | `getParents(): Element[]` | Get all ancestor elements |
|
|
61
|
+
| `findFocusableParent` | `findFocusableParent(): HTMLElement \| undefined` | Find nearest focusable ancestor |
|
|
62
|
+
| `findFirstFocusableChild` | `findFirstFocusableChild(): HTMLElement \| undefined` | Find first focusable descendant |
|
|
63
|
+
| `isOffsetElement` | `isOffsetElement(): boolean` | Check if element is an offset parent |
|
|
64
|
+
| `isVisible` | `isVisible(): boolean` | Check if element is visible |
|
|
65
|
+
|
|
66
|
+
### HTMLElement prototype extensions (side-effect import)
|
|
67
|
+
|
|
68
|
+
| Method | Signature | Description |
|
|
69
|
+
|--------|-----------|-------------|
|
|
70
|
+
| `repaint` | `repaint(): void` | Force a repaint of the element |
|
|
71
|
+
| `getRelativeOffset` | `getRelativeOffset(parent: HTMLElement \| string): { top: number; left: number }` | Get position relative to a parent |
|
|
72
|
+
| `scrollIntoViewIfNeeded` | `scrollIntoViewIfNeeded(target: { top: number; left: number }, offset?: { top: number; left: number }): void` | Scroll to make target position visible |
|
|
73
|
+
|
|
74
|
+
### copyElement
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
function copyElement(event: ClipboardEvent): void
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Copy the content of the focused element to the clipboard via a `ClipboardEvent`.
|
|
81
|
+
|
|
82
|
+
### pasteToElement
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
function pasteToElement(event: ClipboardEvent): void
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Paste clipboard content into the focused element via a `ClipboardEvent`.
|
|
89
|
+
|
|
90
|
+
### getBounds
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
async function getBounds(els: Element[], timeout?: number): Promise<ElementBounds[]>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Get bounding rectangles for multiple elements using `IntersectionObserver`. An optional `timeout` (ms) limits the observation duration.
|
|
97
|
+
|
|
98
|
+
## Utils
|
|
99
|
+
|
|
100
|
+
### downloadBlob
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
function downloadBlob(blob: Blob, fileName: string): void
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Trigger a browser download for the given `Blob` with the specified file name.
|
|
107
|
+
|
|
108
|
+
### DownloadProgress (interface)
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
interface DownloadProgress {
|
|
112
|
+
receivedLength: number;
|
|
113
|
+
contentLength: number;
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### fetchUrlBytes
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
async function fetchUrlBytes(
|
|
121
|
+
url: string,
|
|
122
|
+
options?: { onProgress?: (progress: DownloadProgress) => void },
|
|
123
|
+
): Promise<Uint8Array>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Fetch URL content as a `Uint8Array`. Optionally reports download progress via `onProgress`.
|
|
127
|
+
|
|
128
|
+
### openFileDialog
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
function openFileDialog(options?: {
|
|
132
|
+
accept?: string;
|
|
133
|
+
multiple?: boolean;
|
|
134
|
+
}): Promise<File[] | undefined>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Open a native file picker dialog. Returns selected files, or `undefined` if cancelled.
|
|
138
|
+
|
|
139
|
+
### StoreConfig (interface)
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
interface StoreConfig {
|
|
143
|
+
name: string;
|
|
144
|
+
keyPath: string;
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### IndexedDbStore (class)
|
|
149
|
+
|
|
150
|
+
IndexedDB wrapper providing simple key-value operations.
|
|
151
|
+
|
|
152
|
+
**Constructor:**
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
constructor(dbName: string, dbVersion: number, storeConfigs: StoreConfig[])
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Methods:**
|
|
159
|
+
|
|
160
|
+
| Method | Signature | Description |
|
|
161
|
+
|--------|-----------|-------------|
|
|
162
|
+
| `open` | `open(): Promise<IDBDatabase>` | Open the database connection |
|
|
163
|
+
| `withStore` | `withStore<T>(storeName: string, mode: IDBTransactionMode, fn: (store: IDBObjectStore) => IDBRequest<T>): Promise<T>` | Execute a single-store transaction |
|
|
164
|
+
| `get` | `get<T>(storeName: string, key: IDBValidKey): Promise<T \| undefined>` | Get a value by key |
|
|
165
|
+
| `put` | `put(storeName: string, value: unknown): Promise<void>` | Insert or update a value |
|
|
166
|
+
| `delete` | `delete(storeName: string, key: IDBValidKey): Promise<void>` | Delete a value by key |
|
|
167
|
+
| `getAll` | `getAll<T>(storeName: string): Promise<T[]>` | Get all values in a store |
|
|
168
|
+
| `close` | `close(): void` | Close the database connection |
|
|
169
|
+
|
|
170
|
+
### VirtualFsEntry (interface)
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
interface VirtualFsEntry {
|
|
174
|
+
kind: "file" | "dir";
|
|
175
|
+
dataBase64?: string;
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### IndexedDbVirtualFs (class)
|
|
180
|
+
|
|
181
|
+
Virtual filesystem backed by an `IndexedDbStore`. Stores files and directories as entries in IndexedDB.
|
|
182
|
+
|
|
183
|
+
**Constructor:**
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
constructor(db: IndexedDbStore, storeName: string, keyField: string)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Methods:**
|
|
190
|
+
|
|
191
|
+
| Method | Signature | Description |
|
|
192
|
+
|--------|-----------|-------------|
|
|
193
|
+
| `getEntry` | `getEntry(fullKey: string): Promise<VirtualFsEntry \| undefined>` | Get a filesystem entry by key |
|
|
194
|
+
| `putEntry` | `putEntry(fullKey: string, kind: "file" \| "dir", dataBase64?: string): Promise<void>` | Create or update a filesystem entry |
|
|
195
|
+
| `deleteByPrefix` | `deleteByPrefix(keyPrefix: string): Promise<boolean>` | Delete all entries matching a key prefix |
|
|
196
|
+
| `listChildren` | `listChildren(prefix: string): Promise<{ name: string; isDirectory: boolean }[]>` | List immediate children of a directory |
|
|
197
|
+
| `ensureDir` | `ensureDir(fullKeyBuilder: (dir: string) => string, dirPath: string): Promise<void>` | Recursively ensure a directory path exists |
|
|
198
|
+
|
|
199
|
+
## Usage
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
import "@simplysm/core-browser"; // activate prototype extensions
|
|
203
|
+
|
|
204
|
+
// DOM extensions
|
|
205
|
+
const el = document.querySelector(".my-element")!;
|
|
206
|
+
const parents = el.getParents();
|
|
207
|
+
const child = el.findFirst<HTMLDivElement>(".child");
|
|
208
|
+
|
|
209
|
+
// File download
|
|
210
|
+
import { downloadBlob, fetchUrlBytes } from "@simplysm/core-browser";
|
|
211
|
+
|
|
212
|
+
const bytes = await fetchUrlBytes("/api/data.bin", {
|
|
213
|
+
onProgress: (p) => console.log(`${p.receivedLength}/${p.contentLength}`),
|
|
214
|
+
});
|
|
215
|
+
downloadBlob(new Blob([bytes]), "data.bin");
|
|
216
|
+
|
|
217
|
+
// IndexedDB store
|
|
218
|
+
import { IndexedDbStore } from "@simplysm/core-browser";
|
|
219
|
+
|
|
220
|
+
const store = new IndexedDbStore("myDb", 1, [{ name: "items", keyPath: "id" }]);
|
|
221
|
+
await store.put("items", { id: "1", value: "hello" });
|
|
222
|
+
const item = await store.get("items", "1");
|
|
223
|
+
store.close();
|
|
224
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/core-browser",
|
|
3
|
-
"version": "14.0.
|
|
3
|
+
"version": "14.0.4",
|
|
4
4
|
"description": "심플리즘 패키지 - 코어 (browser)",
|
|
5
5
|
"author": "심플리즘",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -24,6 +24,6 @@
|
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"tabbable": "^6.4.0",
|
|
27
|
-
"@simplysm/core-common": "14.0.
|
|
27
|
+
"@simplysm/core-common": "14.0.4"
|
|
28
28
|
}
|
|
29
29
|
}
|