@iankibetsh/vue-streamline 1.3.7 → 2.0.0
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 +4 -1
- package/package.json +32 -27
- package/src/index.js +6 -7
- package/src/plugins/streamline.js +17 -9
- package/.github/workflows/npm-publish.yml +0 -34
- package/.vscode/extensions.json +0 -3
- package/index.html +0 -12
- package/public/vite.svg +0 -1
- package/src/App.vue +0 -66
- package/src/SimpleGetActionUrl.vue +0 -11
- package/src/composables/getActionUrl.js +0 -7
- package/src/composables/useStreamline.js +0 -169
- package/src/main.js +0 -21
- package/src/style.css +0 -79
- package/src/utils/cache.js +0 -113
- package/vite.config.js +0 -23
package/README.md
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
# Streamline Vue Plugin
|
|
1
|
+
# Streamline Vue Plugin (DEPRECATED — moved into @iankibetsh/sh-core)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
> **⚠️ Deprecated as of v2.** The streamline implementation now ships inside [`@iankibetsh/sh-core`](https://www.npmjs.com/package/@iankibetsh/sh-core) — import `useStreamline` / `getActionUrl` from there. v2 of this package is a thin re-export shim kept for backward compatibility; the `streamlineHeaders` option is ignored (auth is handled by the sh-core API client).
|
|
2
5
|
|
|
3
6
|
A robust Vue 3 plugin designed for seamless integration with Streamline backend services. It delivers reactive state management, intelligent caching, and dynamic action invocation.
|
|
4
7
|
|
package/package.json
CHANGED
|
@@ -1,28 +1,33 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
"version": "
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
2
|
+
"name": "@iankibetsh/vue-streamline",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "DEPRECATED compatibility shim: streamline now lives in @iankibetsh/sh-core. Vue library for streamlining laravel backend services with @iankibet/streamline composer package",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"preview": "vite preview"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": "./src/index.js"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"src/index.js",
|
|
16
|
+
"src/plugins"
|
|
17
|
+
],
|
|
18
|
+
"keywords": [],
|
|
19
|
+
"author": "Iankibet",
|
|
20
|
+
"license": "ISC",
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@iankibetsh/sh-core": "file:../sh-core",
|
|
23
|
+
"@vitejs/plugin-vue": "^6",
|
|
24
|
+
"vite": "^8"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"@iankibetsh/sh-core": "^1",
|
|
28
|
+
"vue": "^3.5"
|
|
29
|
+
},
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
}
|
|
33
|
+
}
|
package/src/index.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// v2: vue-streamline is a compatibility shim over @iankibetsh/sh-core,
|
|
2
|
+
// which now ships streamline as a first-class module. New code should
|
|
3
|
+
// import from '@iankibetsh/sh-core' directly.
|
|
3
4
|
import streamline from './plugins/streamline.js'
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
streamline
|
|
8
|
-
}
|
|
5
|
+
|
|
6
|
+
export { useStreamline, getActionUrl } from '@iankibetsh/sh-core'
|
|
7
|
+
export { streamline }
|
|
@@ -1,13 +1,21 @@
|
|
|
1
|
+
// v2: thin compat shim. The streamline implementation now lives in
|
|
2
|
+
// @iankibetsh/sh-core; this plugin only maps the old options onto the
|
|
3
|
+
// injection keys / window globals the core composable reads.
|
|
1
4
|
const streamline = {
|
|
2
|
-
install(app, options) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
window.
|
|
5
|
+
install (app, options = {}) {
|
|
6
|
+
const streamlineUrl = options.streamlineUrl ?? '/api/streamline'
|
|
7
|
+
const enableCache = options.enableCache ?? true
|
|
8
|
+
|
|
9
|
+
app.provide('streamlineUrl', streamlineUrl)
|
|
10
|
+
app.provide('enableCache', enableCache)
|
|
11
|
+
|
|
12
|
+
window.streamlineUrl = streamlineUrl
|
|
13
|
+
window.enableCache = enableCache
|
|
14
|
+
|
|
15
|
+
if (options.streamlineHeaders) {
|
|
16
|
+
console.warn('[vue-streamline] `streamlineHeaders` is deprecated and ignored: requests are authenticated by the @iankibetsh/sh-core API client (bearer or cookie strategy).')
|
|
17
|
+
}
|
|
10
18
|
}
|
|
11
19
|
}
|
|
12
20
|
|
|
13
|
-
export default streamline
|
|
21
|
+
export default streamline
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
|
|
2
|
-
# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
|
|
3
|
-
|
|
4
|
-
name: Node.js Package
|
|
5
|
-
|
|
6
|
-
on:
|
|
7
|
-
release:
|
|
8
|
-
types: [created]
|
|
9
|
-
|
|
10
|
-
jobs:
|
|
11
|
-
build:
|
|
12
|
-
runs-on: ubuntu-latest
|
|
13
|
-
steps:
|
|
14
|
-
- uses: actions/checkout@v4
|
|
15
|
-
- uses: actions/setup-node@v4
|
|
16
|
-
with:
|
|
17
|
-
node-version: 20
|
|
18
|
-
- run: npm ci
|
|
19
|
-
# - run: npm test
|
|
20
|
-
|
|
21
|
-
publish-npm:
|
|
22
|
-
needs: build
|
|
23
|
-
runs-on: ubuntu-latest
|
|
24
|
-
steps:
|
|
25
|
-
- uses: actions/checkout@v4
|
|
26
|
-
- uses: actions/setup-node@v4
|
|
27
|
-
with:
|
|
28
|
-
node-version: 20
|
|
29
|
-
registry-url: https://registry.npmjs.org/
|
|
30
|
-
- run: npm ci
|
|
31
|
-
- run: npm run build
|
|
32
|
-
- run: npm publish
|
|
33
|
-
env:
|
|
34
|
-
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
|
package/.vscode/extensions.json
DELETED
package/index.html
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Streamline Framework</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<div id="app"></div>
|
|
10
|
-
<script type="module" src="/src/main.js"></script>
|
|
11
|
-
</body>
|
|
12
|
-
</html>
|
package/public/vite.svg
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
package/src/App.vue
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
import useStreamline from './composables/useStreamline.js'
|
|
3
|
-
import { onMounted, ref, toRefs,computed } from 'vue'
|
|
4
|
-
import SimpleGetActionUrl from './SimpleGetActionUrl.vue'
|
|
5
|
-
|
|
6
|
-
const {loading, service:paybillService, getActionUrl,props,confirmAction} = useStreamline('mpesa/paybill',32)
|
|
7
|
-
|
|
8
|
-
const existing = computed(()=>props.paybill)
|
|
9
|
-
const foundPaybill = ref(null)
|
|
10
|
-
|
|
11
|
-
onMounted(()=>{
|
|
12
|
-
// paybillService.getPaybill(32).then(res=>{
|
|
13
|
-
// foundPaybill.value = res
|
|
14
|
-
// })
|
|
15
|
-
})
|
|
16
|
-
const findPaybill = async ()=>{
|
|
17
|
-
// const res = confirmAction('Are you sure?')
|
|
18
|
-
// res.getPaybill(32).then(res=>{
|
|
19
|
-
// foundPaybill.value = res
|
|
20
|
-
// })
|
|
21
|
-
foundPaybill.value = await paybillService.confirm().getPaybill(32, {name: 'ian'})
|
|
22
|
-
.catch(err=>{
|
|
23
|
-
console.log(err)
|
|
24
|
-
})
|
|
25
|
-
}
|
|
26
|
-
const refresh = ()=>{
|
|
27
|
-
paybillService.refresh()
|
|
28
|
-
}
|
|
29
|
-
</script>
|
|
30
|
-
|
|
31
|
-
<template>
|
|
32
|
-
<div>
|
|
33
|
-
<hr/>
|
|
34
|
-
<h3>Destructed: {{ testKey }}</h3>
|
|
35
|
-
<h3>Original: {{ props.testKey }}</h3>
|
|
36
|
-
<h3>Original: {{ props.testKey }}</h3>
|
|
37
|
-
<h3>Original: {{ props.testKey }}</h3>
|
|
38
|
-
<h3>Original: {{ props.testKey }}</h3>
|
|
39
|
-
<h3 class="text-success" >Loading : {{ loading }}</h3>
|
|
40
|
-
<h1 @click="findPaybill">Get Paybill</h1>
|
|
41
|
-
<h1 @click="refresh">Refresh</h1>
|
|
42
|
-
{{ foundPaybill }}
|
|
43
|
-
</div>
|
|
44
|
-
<div class="alert alert-info">
|
|
45
|
-
<h2>Existing</h2>
|
|
46
|
-
<p>
|
|
47
|
-
{{ existing }}
|
|
48
|
-
</p>
|
|
49
|
-
</div>
|
|
50
|
-
<simple-get-action-url/>
|
|
51
|
-
</template>
|
|
52
|
-
|
|
53
|
-
<style scoped>
|
|
54
|
-
.logo {
|
|
55
|
-
height: 6em;
|
|
56
|
-
padding: 1.5em;
|
|
57
|
-
will-change: filter;
|
|
58
|
-
transition: filter 300ms;
|
|
59
|
-
}
|
|
60
|
-
.logo:hover {
|
|
61
|
-
filter: drop-shadow(0 0 2em #646cffaa);
|
|
62
|
-
}
|
|
63
|
-
.logo.vue:hover {
|
|
64
|
-
filter: drop-shadow(0 0 2em #42b883aa);
|
|
65
|
-
}
|
|
66
|
-
</style>
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import { inject, onMounted, reactive, ref } from 'vue'
|
|
2
|
-
import { shApis, shRepo } from '@iankibetsh/shframework'
|
|
3
|
-
import Cache from '../utils/cache'
|
|
4
|
-
|
|
5
|
-
const useStreamline = (stream, ...initialArgs) => {
|
|
6
|
-
let formData = {}
|
|
7
|
-
const loading = ref(false)
|
|
8
|
-
const propertiesFetched = ref(false)
|
|
9
|
-
const confirmationMessage = ref(null)
|
|
10
|
-
|
|
11
|
-
// Cache key for local storage, include initialArgs in the key
|
|
12
|
-
const cacheKey = `streamline_${stream}_${initialArgs.join('_')}`
|
|
13
|
-
|
|
14
|
-
// Inject headers and API endpoint
|
|
15
|
-
let streamlineUrl = inject('streamlineUrl', window.streamlineUrl)
|
|
16
|
-
if (streamlineUrl && streamlineUrl.startsWith('/') && !streamlineUrl.startsWith('//') && typeof window !== 'undefined') {
|
|
17
|
-
streamlineUrl = window.location.origin + streamlineUrl
|
|
18
|
-
}
|
|
19
|
-
const enableCache = inject('enableCache', window.enableCache ?? true)
|
|
20
|
-
|
|
21
|
-
const originalProps = reactive({})
|
|
22
|
-
|
|
23
|
-
// Proxy to intercept access
|
|
24
|
-
const props = new Proxy(originalProps, {
|
|
25
|
-
get(target, property, receiver) {
|
|
26
|
-
if (!propertiesFetched.value) {
|
|
27
|
-
fetchServiceProperties().then(() => target[property])
|
|
28
|
-
}
|
|
29
|
-
return Reflect.get(target, property, receiver) // Return the actual value
|
|
30
|
-
},
|
|
31
|
-
set(target, property, value, receiver) {
|
|
32
|
-
return Reflect.set(target, property, value, receiver) // Update the value
|
|
33
|
-
}
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
const fetchServiceProperties = async (force) => {
|
|
37
|
-
if (!force) {
|
|
38
|
-
if (loading.value || propertiesFetched.value) return
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
try {
|
|
42
|
-
loading.value = true
|
|
43
|
-
const response = await shApis.doPost(streamlineUrl, {
|
|
44
|
-
action: 'onMounted',
|
|
45
|
-
stream,
|
|
46
|
-
params: initialArgs
|
|
47
|
-
})
|
|
48
|
-
assignProperties(response.data)
|
|
49
|
-
if (enableCache) {
|
|
50
|
-
await Cache.set(cacheKey, response.data)
|
|
51
|
-
}
|
|
52
|
-
} catch (error) {
|
|
53
|
-
console.error(`Error fetching properties for stream ${stream}`, error)
|
|
54
|
-
throw error
|
|
55
|
-
} finally {
|
|
56
|
-
propertiesFetched.value = true
|
|
57
|
-
loading.value = false
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const assignProperties = (data) => {
|
|
62
|
-
Object.assign(service, data.properties)
|
|
63
|
-
Object.assign(originalProps, data.properties)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const handler = {
|
|
67
|
-
get(target, prop, receiver) {
|
|
68
|
-
if (prop in target) {
|
|
69
|
-
return target[prop]
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return (...args) => {
|
|
73
|
-
if (prop === 'refresh' || prop === 'reload') {
|
|
74
|
-
return fetchServiceProperties(true)
|
|
75
|
-
}
|
|
76
|
-
if (prop === 'confirm') {
|
|
77
|
-
return confirmAction(args[0] ?? 'Are you sure?')
|
|
78
|
-
}
|
|
79
|
-
let repo = null
|
|
80
|
-
const data = {
|
|
81
|
-
action: prop,
|
|
82
|
-
stream,
|
|
83
|
-
...formData,
|
|
84
|
-
params: args,
|
|
85
|
-
initialParams: initialArgs
|
|
86
|
-
}
|
|
87
|
-
args.forEach(arg => {
|
|
88
|
-
if (arg && typeof arg === 'object' && !Array.isArray(arg)) {
|
|
89
|
-
Object.assign(data, arg)
|
|
90
|
-
}
|
|
91
|
-
})
|
|
92
|
-
if (confirmationMessage.value) {
|
|
93
|
-
repo = shRepo.runPlainRequest(streamlineUrl, null, confirmationMessage.value, data)
|
|
94
|
-
} else {
|
|
95
|
-
repo = shApis
|
|
96
|
-
.doPost(streamlineUrl, data);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
loading.value = true
|
|
100
|
-
return repo.then((response) => {
|
|
101
|
-
loading.value = false
|
|
102
|
-
if (confirmationMessage.value) {
|
|
103
|
-
confirmationMessage.value = null
|
|
104
|
-
|
|
105
|
-
if (!response.isConfirmed) {
|
|
106
|
-
return
|
|
107
|
-
}
|
|
108
|
-
if (response.value?.success) {
|
|
109
|
-
return response.value.response
|
|
110
|
-
} else {
|
|
111
|
-
// throw error
|
|
112
|
-
throw response.value.error
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return response.data
|
|
118
|
-
})
|
|
119
|
-
.catch((error) => {
|
|
120
|
-
loading.value = false
|
|
121
|
-
console.error(`Error calling ${prop} on stream ${stream}`, error)
|
|
122
|
-
throw error
|
|
123
|
-
})
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
const getActionUrl = (action, ...args) => {
|
|
128
|
-
let newStream = stream
|
|
129
|
-
if (action.includes(':')) {
|
|
130
|
-
[newStream, action] = action.split(':')
|
|
131
|
-
}
|
|
132
|
-
const post = {
|
|
133
|
-
action,
|
|
134
|
-
stream: newStream,
|
|
135
|
-
params: args
|
|
136
|
-
}
|
|
137
|
-
return `${streamlineUrl}?${new URLSearchParams(post).toString()}`
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const service = reactive({})
|
|
141
|
-
|
|
142
|
-
// Confirmation wrapper
|
|
143
|
-
const confirmAction = (message) => {
|
|
144
|
-
confirmationMessage.value = message
|
|
145
|
-
return new Proxy(service, handler)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
onMounted(async () => {
|
|
149
|
-
if (enableCache) {
|
|
150
|
-
const cachedData = await Cache.get(cacheKey)
|
|
151
|
-
if (cachedData) {
|
|
152
|
-
assignProperties(cachedData)
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
if (initialArgs.length > 0) {
|
|
156
|
-
fetchServiceProperties()
|
|
157
|
-
}
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
return {
|
|
161
|
-
loading,
|
|
162
|
-
service: new Proxy(service, handler),
|
|
163
|
-
getActionUrl,
|
|
164
|
-
confirmAction,
|
|
165
|
-
props
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
export default useStreamline
|
package/src/main.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { createApp } from 'vue'
|
|
2
|
-
import './style.css'
|
|
3
|
-
import App from './App.vue'
|
|
4
|
-
import streamline from './plugins/streamline.js'
|
|
5
|
-
import { ShFrontend } from '@iankibetsh/shframework'
|
|
6
|
-
|
|
7
|
-
const streamlineHeaders = {
|
|
8
|
-
Authorization: 'Bearer ' + localStorage.getItem('access_token')
|
|
9
|
-
}
|
|
10
|
-
const streamlineUrl = 'http://2022-sharasms.test/api/streamline'
|
|
11
|
-
const app = createApp(App)
|
|
12
|
-
app.use(ShFrontend, {
|
|
13
|
-
baseApiUrl: 'http://2022-sharasms.test/api'
|
|
14
|
-
})
|
|
15
|
-
app.use(streamline,{
|
|
16
|
-
streamlineHeaders,
|
|
17
|
-
streamlineUrl,
|
|
18
|
-
enableCache: true
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
app.mount('#app')
|
package/src/style.css
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
:root {
|
|
2
|
-
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
3
|
-
line-height: 1.5;
|
|
4
|
-
font-weight: 400;
|
|
5
|
-
|
|
6
|
-
color-scheme: light dark;
|
|
7
|
-
color: rgba(255, 255, 255, 0.87);
|
|
8
|
-
background-color: #242424;
|
|
9
|
-
|
|
10
|
-
font-synthesis: none;
|
|
11
|
-
text-rendering: optimizeLegibility;
|
|
12
|
-
-webkit-font-smoothing: antialiased;
|
|
13
|
-
-moz-osx-font-smoothing: grayscale;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
a {
|
|
17
|
-
font-weight: 500;
|
|
18
|
-
color: #646cff;
|
|
19
|
-
text-decoration: inherit;
|
|
20
|
-
}
|
|
21
|
-
a:hover {
|
|
22
|
-
color: #535bf2;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
body {
|
|
26
|
-
margin: 0;
|
|
27
|
-
display: flex;
|
|
28
|
-
place-items: center;
|
|
29
|
-
min-width: 320px;
|
|
30
|
-
min-height: 100vh;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
h1 {
|
|
34
|
-
font-size: 3.2em;
|
|
35
|
-
line-height: 1.1;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
button {
|
|
39
|
-
border-radius: 8px;
|
|
40
|
-
border: 1px solid transparent;
|
|
41
|
-
padding: 0.6em 1.2em;
|
|
42
|
-
font-size: 1em;
|
|
43
|
-
font-weight: 500;
|
|
44
|
-
font-family: inherit;
|
|
45
|
-
background-color: #1a1a1a;
|
|
46
|
-
cursor: pointer;
|
|
47
|
-
transition: border-color 0.25s;
|
|
48
|
-
}
|
|
49
|
-
button:hover {
|
|
50
|
-
border-color: #646cff;
|
|
51
|
-
}
|
|
52
|
-
button:focus,
|
|
53
|
-
button:focus-visible {
|
|
54
|
-
outline: 4px auto -webkit-focus-ring-color;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
.card {
|
|
58
|
-
padding: 2em;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
#app {
|
|
62
|
-
max-width: 1280px;
|
|
63
|
-
margin: 0 auto;
|
|
64
|
-
padding: 2rem;
|
|
65
|
-
text-align: center;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
@media (prefers-color-scheme: light) {
|
|
69
|
-
:root {
|
|
70
|
-
color: #213547;
|
|
71
|
-
background-color: #ffffff;
|
|
72
|
-
}
|
|
73
|
-
a:hover {
|
|
74
|
-
color: #747bff;
|
|
75
|
-
}
|
|
76
|
-
button {
|
|
77
|
-
background-color: #f9f9f9;
|
|
78
|
-
}
|
|
79
|
-
}
|
package/src/utils/cache.js
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
const DB_NAME = 'streamline_cache'
|
|
2
|
-
const STORE_NAME = 'properties'
|
|
3
|
-
const DB_VERSION = 1
|
|
4
|
-
|
|
5
|
-
const openDB = () => {
|
|
6
|
-
return new Promise((resolve, reject) => {
|
|
7
|
-
const request = indexedDB.open(DB_NAME, DB_VERSION)
|
|
8
|
-
|
|
9
|
-
request.onupgradeneeded = (event) => {
|
|
10
|
-
const db = event.target.result
|
|
11
|
-
if (!db.objectStoreNames.contains(STORE_NAME)) {
|
|
12
|
-
db.createObjectStore(STORE_NAME)
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
request.onsuccess = (event) => {
|
|
17
|
-
resolve(event.target.result)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
request.onerror = (event) => {
|
|
21
|
-
reject(event.target.error)
|
|
22
|
-
}
|
|
23
|
-
})
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const Cache = {
|
|
27
|
-
async get(key) {
|
|
28
|
-
try {
|
|
29
|
-
const db = await openDB()
|
|
30
|
-
return new Promise((resolve, reject) => {
|
|
31
|
-
const transaction = db.transaction(STORE_NAME, 'readonly')
|
|
32
|
-
const store = transaction.objectStore(STORE_NAME)
|
|
33
|
-
const request = store.get(key)
|
|
34
|
-
|
|
35
|
-
request.onsuccess = () => {
|
|
36
|
-
resolve(request.result)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
request.onerror = () => {
|
|
40
|
-
reject(request.error)
|
|
41
|
-
}
|
|
42
|
-
})
|
|
43
|
-
} catch (error) {
|
|
44
|
-
console.error('Error getting from IndexedDB cache', error)
|
|
45
|
-
return null
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
async set(key, value) {
|
|
50
|
-
try {
|
|
51
|
-
const db = await openDB()
|
|
52
|
-
return new Promise((resolve, reject) => {
|
|
53
|
-
const transaction = db.transaction(STORE_NAME, 'readwrite')
|
|
54
|
-
const store = transaction.objectStore(STORE_NAME)
|
|
55
|
-
const request = store.put(value, key)
|
|
56
|
-
|
|
57
|
-
request.onsuccess = () => {
|
|
58
|
-
resolve()
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
request.onerror = () => {
|
|
62
|
-
reject(request.error)
|
|
63
|
-
}
|
|
64
|
-
})
|
|
65
|
-
} catch (error) {
|
|
66
|
-
console.error('Error setting in IndexedDB cache', error)
|
|
67
|
-
}
|
|
68
|
-
},
|
|
69
|
-
|
|
70
|
-
async delete(key) {
|
|
71
|
-
try {
|
|
72
|
-
const db = await openDB()
|
|
73
|
-
return new Promise((resolve, reject) => {
|
|
74
|
-
const transaction = db.transaction(STORE_NAME, 'readwrite')
|
|
75
|
-
const store = transaction.objectStore(STORE_NAME)
|
|
76
|
-
const request = store.delete(key)
|
|
77
|
-
|
|
78
|
-
request.onsuccess = () => {
|
|
79
|
-
resolve()
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
request.onerror = () => {
|
|
83
|
-
reject(request.error)
|
|
84
|
-
}
|
|
85
|
-
})
|
|
86
|
-
} catch (error) {
|
|
87
|
-
console.error('Error deleting from IndexedDB cache', error)
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
async clear() {
|
|
92
|
-
try {
|
|
93
|
-
const db = await openDB()
|
|
94
|
-
return new Promise((resolve, reject) => {
|
|
95
|
-
const transaction = db.transaction(STORE_NAME, 'readwrite')
|
|
96
|
-
const store = transaction.objectStore(STORE_NAME)
|
|
97
|
-
const request = store.clear()
|
|
98
|
-
|
|
99
|
-
request.onsuccess = () => {
|
|
100
|
-
resolve()
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
request.onerror = () => {
|
|
104
|
-
reject(request.error)
|
|
105
|
-
}
|
|
106
|
-
})
|
|
107
|
-
} catch (error) {
|
|
108
|
-
console.error('Error clearing IndexedDB cache', error)
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export default Cache
|
package/vite.config.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
// vite.config.js
|
|
2
|
-
import { defineConfig } from 'vite';
|
|
3
|
-
import vue from '@vitejs/plugin-vue';
|
|
4
|
-
|
|
5
|
-
export default defineConfig({
|
|
6
|
-
plugins: [vue()],
|
|
7
|
-
build: {
|
|
8
|
-
lib: {
|
|
9
|
-
entry: './src/index.js',
|
|
10
|
-
name: 'VueStreamline',
|
|
11
|
-
fileName: (format) => `vue-streamline.${format}.js`,
|
|
12
|
-
},
|
|
13
|
-
rollupOptions: {
|
|
14
|
-
// Make sure to externalize deps that shouldn't be bundled into your library
|
|
15
|
-
external: ['vue'],
|
|
16
|
-
output: {
|
|
17
|
-
globals: {
|
|
18
|
-
vue: 'Vue',
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
});
|