mirror of
https://github.com/lana-k/sqliteviz.git
synced 2025-12-10 03:58:54 +08:00
format
This commit is contained in:
@@ -2,7 +2,7 @@ import * as dereference from 'react-chart-editor/lib/lib/dereference'
|
||||
import plotly from 'plotly.js'
|
||||
import { nanoid } from 'nanoid'
|
||||
|
||||
export function getOptionsFromDataSources (dataSources) {
|
||||
export function getOptionsFromDataSources(dataSources) {
|
||||
if (!dataSources) {
|
||||
return []
|
||||
}
|
||||
@@ -13,7 +13,7 @@ export function getOptionsFromDataSources (dataSources) {
|
||||
}))
|
||||
}
|
||||
|
||||
export function getOptionsForSave (state, dataSources) {
|
||||
export function getOptionsForSave(state, dataSources) {
|
||||
// we don't need to save the data, only settings
|
||||
// so we modify state.data using dereference
|
||||
const stateCopy = JSON.parse(JSON.stringify(state))
|
||||
@@ -25,7 +25,7 @@ export function getOptionsForSave (state, dataSources) {
|
||||
return stateCopy
|
||||
}
|
||||
|
||||
export async function getImageDataUrl (element, type) {
|
||||
export async function getImageDataUrl(element, type) {
|
||||
const chartElement = element.querySelector('.js-plotly-plot')
|
||||
return await plotly.toImage(chartElement, {
|
||||
format: type,
|
||||
@@ -34,7 +34,7 @@ export async function getImageDataUrl (element, type) {
|
||||
})
|
||||
}
|
||||
|
||||
export function getChartData (element) {
|
||||
export function getChartData(element) {
|
||||
const chartElement = element.querySelector('.js-plotly-plot')
|
||||
return {
|
||||
data: chartElement.data,
|
||||
@@ -42,7 +42,7 @@ export function getChartData (element) {
|
||||
}
|
||||
}
|
||||
|
||||
export function getHtml (options) {
|
||||
export function getHtml(options) {
|
||||
const chartId = nanoid()
|
||||
return `
|
||||
<script src="https://cdn.plot.ly/plotly-latest.js" charset="UTF-8"></script>
|
||||
|
||||
@@ -7,7 +7,7 @@ const hintsByCode = {
|
||||
}
|
||||
|
||||
export default {
|
||||
getResult (source, columns) {
|
||||
getResult(source, columns) {
|
||||
const result = {
|
||||
columns: columns || []
|
||||
}
|
||||
@@ -52,7 +52,7 @@ export default {
|
||||
return result
|
||||
},
|
||||
|
||||
prepareForExport (resultSet) {
|
||||
prepareForExport(resultSet) {
|
||||
const columns = resultSet.columns
|
||||
const rowCount = resultSet.values[columns[0]].length
|
||||
const result = {
|
||||
@@ -61,13 +61,15 @@ export default {
|
||||
}
|
||||
|
||||
for (let rowNumber = 0; rowNumber < rowCount; rowNumber++) {
|
||||
result.data.push(columns.map(column => resultSet.values[column][rowNumber]))
|
||||
result.data.push(
|
||||
columns.map(column => resultSet.values[column][rowNumber])
|
||||
)
|
||||
}
|
||||
|
||||
return result
|
||||
},
|
||||
|
||||
parse (file, config = {}) {
|
||||
parse(file, config = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const defaultConfig = {
|
||||
delimiter: '', // auto-detect
|
||||
@@ -122,7 +124,7 @@ export default {
|
||||
})
|
||||
},
|
||||
|
||||
serialize (resultSet) {
|
||||
serialize(resultSet) {
|
||||
return Papa.unparse(this.prepareForExport(resultSet), { delimiter: '\t' })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,11 @@ import wasmUrl from 'sql.js/dist/sql-wasm.wasm?url'
|
||||
let SQL = null
|
||||
const sqlModuleReady = initSqlJs({
|
||||
locateFile: () => wasmUrl
|
||||
}).then(sqlModule => { SQL = sqlModule })
|
||||
}).then(sqlModule => {
|
||||
SQL = sqlModule
|
||||
})
|
||||
|
||||
function _getDataSourcesFromSqlResult (sqlResult) {
|
||||
function _getDataSourcesFromSqlResult(sqlResult) {
|
||||
if (!sqlResult) {
|
||||
return {}
|
||||
}
|
||||
@@ -19,31 +21,30 @@ function _getDataSourcesFromSqlResult (sqlResult) {
|
||||
}
|
||||
|
||||
export default class Sql {
|
||||
constructor () {
|
||||
constructor() {
|
||||
this.db = null
|
||||
}
|
||||
|
||||
static build () {
|
||||
return sqlModuleReady
|
||||
.then(() => {
|
||||
return new Sql()
|
||||
})
|
||||
static build() {
|
||||
return sqlModuleReady.then(() => {
|
||||
return new Sql()
|
||||
})
|
||||
}
|
||||
|
||||
createDb (buffer) {
|
||||
createDb(buffer) {
|
||||
if (this.db != null) this.db.close()
|
||||
this.db = new SQL.Database(buffer)
|
||||
return this.db
|
||||
}
|
||||
|
||||
open (buffer) {
|
||||
open(buffer) {
|
||||
this.createDb(buffer && new Uint8Array(buffer))
|
||||
return {
|
||||
ready: true
|
||||
}
|
||||
}
|
||||
|
||||
exec (sql, params) {
|
||||
exec(sql, params) {
|
||||
if (this.db === null) {
|
||||
this.createDb()
|
||||
}
|
||||
@@ -59,7 +60,7 @@ export default class Sql {
|
||||
})
|
||||
}
|
||||
|
||||
import (tabName, data, progressCounterId, progressCallback, chunkSize = 1500) {
|
||||
import(tabName, data, progressCounterId, progressCallback, chunkSize = 1500) {
|
||||
if (this.db === null) {
|
||||
this.createDb()
|
||||
}
|
||||
@@ -80,7 +81,10 @@ export default class Sql {
|
||||
}
|
||||
this.db.exec('COMMIT')
|
||||
count++
|
||||
progressCallback({ progress: 100 * (count / chunksAmount), id: progressCounterId })
|
||||
progressCallback({
|
||||
progress: 100 * (count / chunksAmount),
|
||||
id: progressCounterId
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -88,11 +92,11 @@ export default class Sql {
|
||||
}
|
||||
}
|
||||
|
||||
export () {
|
||||
export() {
|
||||
return this.db.export()
|
||||
}
|
||||
|
||||
close () {
|
||||
close() {
|
||||
if (this.db) {
|
||||
this.db.close()
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
export default {
|
||||
* generateChunks (data, size) {
|
||||
*generateChunks(data, size) {
|
||||
const matrix = Object.keys(data).map(col => data[col])
|
||||
const [row] = matrix
|
||||
const transposedMatrix = row.map((value, column) => matrix.map(row => row[column]))
|
||||
const transposedMatrix = row.map((value, column) =>
|
||||
matrix.map(row => row[column])
|
||||
)
|
||||
|
||||
const count = Math.ceil(transposedMatrix.length / size)
|
||||
|
||||
@@ -13,13 +15,13 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
getInsertStmt (tabName, columns) {
|
||||
getInsertStmt(tabName, columns) {
|
||||
const colList = `"${columns.join('", "')}"`
|
||||
const params = columns.map(() => '?').join(', ')
|
||||
return `INSERT INTO "${tabName}" (${colList}) VALUES (${params});`
|
||||
},
|
||||
|
||||
getCreateStatement (tabName, data) {
|
||||
getCreateStatement(tabName, data) {
|
||||
let result = `CREATE table "${tabName}"(`
|
||||
for (const col in data) {
|
||||
// Get the first row of values to determine types
|
||||
@@ -38,7 +40,8 @@ export default {
|
||||
type = 'TEXT'
|
||||
break
|
||||
}
|
||||
default: type = 'TEXT'
|
||||
default:
|
||||
type = 'TEXT'
|
||||
}
|
||||
result += `"${col}" ${type}, `
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import Sql from './_sql'
|
||||
|
||||
const sqlReady = Sql.build()
|
||||
|
||||
function processMsg (sql) {
|
||||
function processMsg(sql) {
|
||||
const data = this
|
||||
switch (data && data.action) {
|
||||
case 'open':
|
||||
@@ -28,14 +28,12 @@ function processMsg (sql) {
|
||||
}
|
||||
}
|
||||
|
||||
function onError (error) {
|
||||
function onError(error) {
|
||||
return {
|
||||
error: error.message
|
||||
}
|
||||
}
|
||||
|
||||
registerPromiseWorker(data => {
|
||||
return sqlReady
|
||||
.then(processMsg.bind(data))
|
||||
.catch(onError)
|
||||
return sqlReady.then(processMsg.bind(data)).catch(onError)
|
||||
})
|
||||
|
||||
@@ -6,11 +6,10 @@ import PromiseWorker from 'promise-worker'
|
||||
|
||||
import events from '@/lib/utils/events'
|
||||
|
||||
function getNewDatabase () {
|
||||
const worker = new Worker(
|
||||
new URL('./_worker.js', import.meta.url),
|
||||
{ type: 'module' }
|
||||
)
|
||||
function getNewDatabase() {
|
||||
const worker = new Worker(new URL('./_worker.js', import.meta.url), {
|
||||
type: 'module'
|
||||
})
|
||||
return new Database(worker)
|
||||
}
|
||||
|
||||
@@ -20,7 +19,7 @@ export default {
|
||||
|
||||
let progressCounterIds = 0
|
||||
class Database {
|
||||
constructor (worker) {
|
||||
constructor(worker) {
|
||||
this.dbName = null
|
||||
this.schema = null
|
||||
this.worker = worker
|
||||
@@ -31,29 +30,33 @@ class Database {
|
||||
const progress = e.data.progress
|
||||
if (progress !== undefined) {
|
||||
const id = e.data.id
|
||||
this.importProgresses[id].dispatchEvent(new CustomEvent('progress', {
|
||||
detail: progress
|
||||
}))
|
||||
this.importProgresses[id].dispatchEvent(
|
||||
new CustomEvent('progress', {
|
||||
detail: progress
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
shutDown () {
|
||||
shutDown() {
|
||||
this.worker.terminate()
|
||||
}
|
||||
|
||||
createProgressCounter (callback) {
|
||||
createProgressCounter(callback) {
|
||||
const id = progressCounterIds++
|
||||
this.importProgresses[id] = new EventTarget()
|
||||
this.importProgresses[id].addEventListener('progress', e => { callback(e.detail) })
|
||||
this.importProgresses[id].addEventListener('progress', e => {
|
||||
callback(e.detail)
|
||||
})
|
||||
return id
|
||||
}
|
||||
|
||||
deleteProgressCounter (id) {
|
||||
deleteProgressCounter(id) {
|
||||
delete this.importProgresses[id]
|
||||
}
|
||||
|
||||
async addTableFromCsv (tabName, data, progressCounterId) {
|
||||
async addTableFromCsv(tabName, data, progressCounterId) {
|
||||
const result = await this.pw.postMessage({
|
||||
action: 'import',
|
||||
data,
|
||||
@@ -68,9 +71,12 @@ class Database {
|
||||
this.refreshSchema()
|
||||
}
|
||||
|
||||
async loadDb (file) {
|
||||
async loadDb(file) {
|
||||
const fileContent = file ? await fu.readAsArrayBuffer(file) : null
|
||||
const res = await this.pw.postMessage({ action: 'open', buffer: fileContent })
|
||||
const res = await this.pw.postMessage({
|
||||
action: 'open',
|
||||
buffer: fileContent
|
||||
})
|
||||
|
||||
if (res.error) {
|
||||
throw new Error(res.error)
|
||||
@@ -85,7 +91,7 @@ class Database {
|
||||
})
|
||||
}
|
||||
|
||||
async refreshSchema () {
|
||||
async refreshSchema() {
|
||||
const getSchemaSql = `
|
||||
WITH columns as (
|
||||
SELECT
|
||||
@@ -103,7 +109,7 @@ class Database {
|
||||
this.schema = JSON.parse(result.values.objects[0])
|
||||
}
|
||||
|
||||
async execute (commands) {
|
||||
async execute(commands) {
|
||||
await this.pw.postMessage({ action: 'reopen' })
|
||||
const results = await this.pw.postMessage({ action: 'exec', sql: commands })
|
||||
|
||||
@@ -114,7 +120,7 @@ class Database {
|
||||
return results[results.length - 1]
|
||||
}
|
||||
|
||||
async export (fileName) {
|
||||
async export(fileName) {
|
||||
const data = await this.pw.postMessage({ action: 'export' })
|
||||
|
||||
if (data.error) {
|
||||
@@ -124,13 +130,15 @@ class Database {
|
||||
events.send('database.export', data.byteLength, { to: 'sqlite' })
|
||||
}
|
||||
|
||||
async validateTableName (name) {
|
||||
async validateTableName(name) {
|
||||
if (name.startsWith('sqlite_')) {
|
||||
throw new Error("Table name can't start with sqlite_")
|
||||
}
|
||||
|
||||
if (/[^\w]/.test(name)) {
|
||||
throw new Error('Table name can contain only letters, digits and underscores')
|
||||
throw new Error(
|
||||
'Table name can contain only letters, digits and underscores'
|
||||
)
|
||||
}
|
||||
|
||||
if (/^(\d)/.test(name)) {
|
||||
@@ -140,7 +148,7 @@ class Database {
|
||||
await this.execute(`BEGIN; CREATE TABLE "${name}"(id); ROLLBACK;`)
|
||||
}
|
||||
|
||||
sanitizeTableName (tabName) {
|
||||
sanitizeTableName(tabName) {
|
||||
return tabName
|
||||
.replace(/[^\w]/g, '_') // replace everything that is not letter, digit or _ with _
|
||||
.replace(/^(\d)/, '_$1') // add _ at beginning if starts with digit
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export default {
|
||||
_migrate (installedVersion, inquiries) {
|
||||
_migrate(installedVersion, inquiries) {
|
||||
if (installedVersion === 1) {
|
||||
inquiries.forEach(inquire => {
|
||||
inquire.viewType = 'chart'
|
||||
|
||||
@@ -7,7 +7,7 @@ const migrate = migration._migrate
|
||||
|
||||
export default {
|
||||
version: 2,
|
||||
getStoredInquiries () {
|
||||
getStoredInquiries() {
|
||||
let myInquiries = JSON.parse(localStorage.getItem('myInquiries'))
|
||||
if (!myInquiries) {
|
||||
const oldInquiries = localStorage.getItem('myQueries')
|
||||
@@ -22,7 +22,7 @@ export default {
|
||||
return (myInquiries && myInquiries.inquiries) || []
|
||||
},
|
||||
|
||||
duplicateInquiry (baseInquiry) {
|
||||
duplicateInquiry(baseInquiry) {
|
||||
const newInquiry = JSON.parse(JSON.stringify(baseInquiry))
|
||||
newInquiry.name = newInquiry.name + ' Copy'
|
||||
newInquiry.id = nanoid()
|
||||
@@ -32,21 +32,28 @@ export default {
|
||||
return newInquiry
|
||||
},
|
||||
|
||||
isTabNeedName (inquiryTab) {
|
||||
isTabNeedName(inquiryTab) {
|
||||
return inquiryTab.isPredefined || !inquiryTab.name
|
||||
},
|
||||
|
||||
updateStorage (inquiries) {
|
||||
localStorage.setItem('myInquiries', JSON.stringify({ version: this.version, inquiries }))
|
||||
updateStorage(inquiries) {
|
||||
localStorage.setItem(
|
||||
'myInquiries',
|
||||
JSON.stringify({ version: this.version, inquiries })
|
||||
)
|
||||
},
|
||||
|
||||
serialiseInquiries (inquiryList) {
|
||||
serialiseInquiries(inquiryList) {
|
||||
const preparedData = JSON.parse(JSON.stringify(inquiryList))
|
||||
preparedData.forEach(inquiry => delete inquiry.isPredefined)
|
||||
return JSON.stringify({ version: this.version, inquiries: preparedData }, null, 4)
|
||||
return JSON.stringify(
|
||||
{ version: this.version, inquiries: preparedData },
|
||||
null,
|
||||
4
|
||||
)
|
||||
},
|
||||
|
||||
deserialiseInquiries (str) {
|
||||
deserialiseInquiries(str) {
|
||||
const inquiries = JSON.parse(str)
|
||||
let inquiryList = []
|
||||
if (!inquiries.version) {
|
||||
@@ -59,7 +66,9 @@ export default {
|
||||
|
||||
// Generate new ids if they are the same as existing inquiries
|
||||
inquiryList.forEach(inquiry => {
|
||||
const allInquiriesIds = this.getStoredInquiries().map(inquiry => inquiry.id)
|
||||
const allInquiriesIds = this.getStoredInquiries().map(
|
||||
inquiry => inquiry.id
|
||||
)
|
||||
if (allInquiriesIds.includes(inquiry.id)) {
|
||||
inquiry.id = nanoid()
|
||||
}
|
||||
@@ -68,24 +77,23 @@ export default {
|
||||
return inquiryList
|
||||
},
|
||||
|
||||
importInquiries () {
|
||||
return fu.importFile()
|
||||
.then(str => {
|
||||
const inquires = this.deserialiseInquiries(str)
|
||||
importInquiries() {
|
||||
return fu.importFile().then(str => {
|
||||
const inquires = this.deserialiseInquiries(str)
|
||||
|
||||
events.send('inquiry.import', inquires.length)
|
||||
events.send('inquiry.import', inquires.length)
|
||||
|
||||
return inquires
|
||||
})
|
||||
return inquires
|
||||
})
|
||||
},
|
||||
export (inquiryList, fileName) {
|
||||
export(inquiryList, fileName) {
|
||||
const jsonStr = this.serialiseInquiries(inquiryList)
|
||||
fu.exportToFile(jsonStr, fileName)
|
||||
|
||||
events.send('inquiry.export', inquiryList.length)
|
||||
},
|
||||
|
||||
async readPredefinedInquiries () {
|
||||
async readPredefinedInquiries() {
|
||||
const res = await fu.readFile('./inquiries.json')
|
||||
const data = await res.json()
|
||||
|
||||
|
||||
@@ -3,12 +3,14 @@ import time from '@/lib/utils/time'
|
||||
import events from '@/lib/utils/events'
|
||||
|
||||
export default class Tab {
|
||||
constructor (state, inquiry = {}) {
|
||||
constructor(state, inquiry = {}) {
|
||||
this.id = inquiry.id || nanoid()
|
||||
this.name = inquiry.id ? inquiry.name : null
|
||||
this.tempName = inquiry.name || (state.untitledLastIndex
|
||||
? `Untitled ${state.untitledLastIndex}`
|
||||
: 'Untitled')
|
||||
this.tempName =
|
||||
inquiry.name ||
|
||||
(state.untitledLastIndex
|
||||
? `Untitled ${state.untitledLastIndex}`
|
||||
: 'Untitled')
|
||||
this.query = inquiry.query
|
||||
this.viewOptions = inquiry.viewOptions || undefined
|
||||
this.isPredefined = inquiry.isPredefined
|
||||
@@ -28,7 +30,7 @@ export default class Tab {
|
||||
this.state = state
|
||||
}
|
||||
|
||||
async execute () {
|
||||
async execute() {
|
||||
this.isGettingResults = true
|
||||
this.result = null
|
||||
this.error = null
|
||||
@@ -39,7 +41,8 @@ export default class Tab {
|
||||
this.time = time.getPeriod(start, new Date())
|
||||
|
||||
if (this.result && this.result.values) {
|
||||
events.send('resultset.create',
|
||||
events.send(
|
||||
'resultset.create',
|
||||
this.result.values[this.result.columns[0]].length
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,14 +2,14 @@ import Lib from 'plotly.js/src/lib'
|
||||
import dataUrlToBlob from 'dataurl-to-blob'
|
||||
|
||||
export default {
|
||||
async copyText (str, notifyMessage) {
|
||||
async copyText(str, notifyMessage) {
|
||||
await navigator.clipboard.writeText(str)
|
||||
if (notifyMessage) {
|
||||
Lib.notifier(notifyMessage, 'long')
|
||||
}
|
||||
},
|
||||
|
||||
async copyImage (source) {
|
||||
async copyImage(source) {
|
||||
if (source instanceof HTMLCanvasElement) {
|
||||
return this._copyCanvas(source)
|
||||
} else {
|
||||
@@ -17,24 +17,29 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
async _copyBlob (blob) {
|
||||
async _copyBlob(blob) {
|
||||
await navigator.clipboard.write([
|
||||
new ClipboardItem({ // eslint-disable-line no-undef
|
||||
new ClipboardItem({
|
||||
// eslint-disable-line no-undef
|
||||
[blob.type]: blob
|
||||
})
|
||||
])
|
||||
},
|
||||
|
||||
async _copyFromDataUrl (url) {
|
||||
async _copyFromDataUrl(url) {
|
||||
const blob = dataUrlToBlob(url)
|
||||
await this._copyBlob(blob)
|
||||
Lib.notifier('Image copied to clipboard successfully', 'long')
|
||||
},
|
||||
|
||||
async _copyCanvas (canvas) {
|
||||
canvas.toBlob(async (blob) => {
|
||||
await this._copyBlob(blob)
|
||||
Lib.notifier('Image copied to clipboard successfully', 'long')
|
||||
}, 'image/png', 1)
|
||||
async _copyCanvas(canvas) {
|
||||
canvas.toBlob(
|
||||
async blob => {
|
||||
await this._copyBlob(blob)
|
||||
Lib.notifier('Image copied to clipboard successfully', 'long')
|
||||
},
|
||||
'image/png',
|
||||
1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export default {
|
||||
send (name, value, labels) {
|
||||
send(name, value, labels) {
|
||||
const event = new CustomEvent('sqliteviz-app-event', {
|
||||
detail: {
|
||||
name,
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
export default {
|
||||
isJSON (file) {
|
||||
isJSON(file) {
|
||||
return file && file.type === 'application/json'
|
||||
},
|
||||
isNDJSON (file) {
|
||||
isNDJSON(file) {
|
||||
return file && file.name.endsWith('.ndjson')
|
||||
},
|
||||
isDatabase (file) {
|
||||
isDatabase(file) {
|
||||
const dbTypes = ['application/vnd.sqlite3', 'application/x-sqlite3']
|
||||
return file.type
|
||||
? dbTypes.includes(file.type)
|
||||
: /\.(db|sqlite(3)?)+$/.test(file.name)
|
||||
},
|
||||
|
||||
getFileName (file) {
|
||||
getFileName(file) {
|
||||
return file.name.replace(/\.[^.]+$/, '')
|
||||
},
|
||||
|
||||
downloadFromUrl (url, fileName) {
|
||||
downloadFromUrl(url, fileName) {
|
||||
// Create downloader
|
||||
const downloader = document.createElement('a')
|
||||
downloader.href = url
|
||||
@@ -29,7 +29,7 @@ export default {
|
||||
URL.revokeObjectURL(url)
|
||||
},
|
||||
|
||||
async exportToFile (str, fileName, type = 'octet/stream') {
|
||||
async exportToFile(str, fileName, type = 'octet/stream') {
|
||||
const blob = new Blob([str], { type })
|
||||
const url = URL.createObjectURL(blob)
|
||||
this.downloadFromUrl(url, fileName)
|
||||
@@ -40,7 +40,7 @@ export default {
|
||||
* it will be an unsettled promise. But it's grabbed by
|
||||
* the garbage collector (tested with FinalizationRegistry).
|
||||
*/
|
||||
getFileFromUser (type) {
|
||||
getFileFromUser(type) {
|
||||
return new Promise(resolve => {
|
||||
const uploader = document.createElement('input')
|
||||
|
||||
@@ -56,14 +56,13 @@ export default {
|
||||
})
|
||||
},
|
||||
|
||||
importFile () {
|
||||
return this.getFileFromUser('.json')
|
||||
.then(file => {
|
||||
return this.getFileContent(file)
|
||||
})
|
||||
importFile() {
|
||||
return this.getFileFromUser('.json').then(file => {
|
||||
return this.getFileContent(file)
|
||||
})
|
||||
},
|
||||
|
||||
getFileContent (file) {
|
||||
getFileContent(file) {
|
||||
const reader = new FileReader()
|
||||
return new Promise(resolve => {
|
||||
reader.onload = e => resolve(e.target.result)
|
||||
@@ -71,11 +70,11 @@ export default {
|
||||
})
|
||||
},
|
||||
|
||||
readFile (path) {
|
||||
readFile(path) {
|
||||
return fetch(path)
|
||||
},
|
||||
|
||||
readAsArrayBuffer (file) {
|
||||
readAsArrayBuffer(file) {
|
||||
const fileReader = new FileReader()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
export default {
|
||||
getPeriod (start, end) {
|
||||
getPeriod(start, end) {
|
||||
const diff = end.getTime() - start.getTime()
|
||||
const seconds = diff / 1000
|
||||
return seconds.toFixed(3) + 's'
|
||||
},
|
||||
|
||||
debounce (func, ms) {
|
||||
debounce(func, ms) {
|
||||
let timeout
|
||||
return function () {
|
||||
clearTimeout(timeout)
|
||||
@@ -13,9 +13,11 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
sleep (ms) {
|
||||
sleep(ms) {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => { resolve() }, ms)
|
||||
setTimeout(() => {
|
||||
resolve()
|
||||
}, ms)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user