most-box 0.2.7 → 0.2.8
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 +9 -1
- package/electron/main.js +30 -420
- package/electron/preload.js +1 -16
- package/electron/updateChecker.js +6 -3
- package/electron/updateChecker.test.js +13 -97
- package/out/admin/index.html +0 -0
- package/out/app/index.html +0 -0
- package/out/assets/{FilePreviewOverlay-CW8lKJCw.js → FilePreviewOverlay-D8H61qbp.js} +1 -1
- package/out/assets/LanguageToggle-CSQtRZ3A.js +1 -0
- package/out/assets/MarketingHeader-CrYsQsQ5.js +1 -0
- package/out/assets/MarketingLayout-CQurMOSD.js +1 -0
- package/out/assets/{MarketingThemeToggle-Cl7PhFgv.js → MarketingThemeToggle-CIKP8x9W.js} +1 -1
- package/out/assets/{MilkdownEditor-B5SKAyjg.js → MilkdownEditor-DrsyaR4h.js} +1 -1
- package/out/assets/{OpenSidebarButton-Bdx86oG8.js → OpenSidebarButton-DnEgqP0S.js} +1 -1
- package/out/assets/{SidebarAccount-c8jirEMF.js → SidebarAccount-B4OAl0as.js} +1 -1
- package/out/assets/SidebarHomeLink-BdsUM4Kt.js +1 -0
- package/out/assets/arrow-right-BU9c_SL4.js +1 -0
- package/out/assets/{circle-alert-Dkgyw_GE.js → circle-alert-iuHzciph.js} +1 -1
- package/out/assets/{copy-KIwotKoP.js → copy-DEzFUzeX.js} +1 -1
- package/out/assets/{download-DPA-3LpR.js → download-jEPn2njL.js} +1 -1
- package/out/assets/{downloadValidation-CH8BeY7_.js → downloadValidation-DbVOwdmC.js} +1 -1
- package/out/assets/{external-link-BmR2rZ80.js → external-link-BFaoZeK0.js} +1 -1
- package/out/assets/{file-text-BJQfDW9r.js → file-text-DPA1riJ_.js} +1 -1
- package/out/assets/{folder-Gb80aQnO.js → folder-Cfgc70_F.js} +1 -1
- package/out/assets/{hard-drive-P2dGA7FX.js → hard-drive-Dar_AZEq.js} +1 -1
- package/out/assets/i18n-NjvOSuV6.js +1 -0
- package/out/assets/index-BZ-f0CZd.js +31 -0
- package/out/assets/index-Cde4g_dk.css +1 -0
- package/out/assets/index.lazy-B7AbDiMU.js +3 -0
- package/out/assets/{index.lazy-DAKkwnV2.js → index.lazy-BsciBHf_.js} +1 -1
- package/out/assets/{index.lazy-B7u3Ztoe.js → index.lazy-BxoGfWEW.js} +1 -1
- package/out/assets/index.lazy-CKbrHko5.js +1 -0
- package/out/assets/index.lazy-CgKPe02l.js +1 -0
- package/out/assets/index.lazy-Citucq1G.js +1 -0
- package/out/assets/index.lazy-CvKEcWlH.js +2 -0
- package/out/assets/{index.lazy-CIqPn0cy.js → index.lazy-DB9Ht9LJ.js} +1 -1
- package/out/assets/index.lazy-DVeqmqaA.js +1 -0
- package/out/assets/index.lazy-hF807bh0.js +1 -0
- package/out/assets/index.lazy-oFaoa4qT.js +1 -0
- package/out/assets/{index.lazy-Bh4jDrUl.js → index.lazy-rfgjFZNH.js} +1 -1
- package/out/assets/index.lazy-zpQXhgmn.js +2 -0
- package/out/assets/{key-round-DvpIlAJY.js → key-round-DNcpSuMw.js} +1 -1
- package/out/assets/{loader-8eVY8_SD.js → loader-BXQtdens.js} +1 -1
- package/out/assets/{lock-Cvtl60UJ.js → lock-CLIE8cct.js} +1 -1
- package/out/assets/{message-square-JK7ABH3O.js → message-square-Dp09WY1I.js} +1 -1
- package/out/assets/{mp-CMvgV1-c.js → mp-B6kdA94c.js} +1 -1
- package/out/assets/{music-YRSH1Jq6.js → music-B19Tg557.js} +1 -1
- package/out/assets/{notebook-pen-BjGx0coX.js → notebook-pen-C8TlK5sB.js} +1 -1
- package/out/assets/play-B-BjsTZz.js +1 -0
- package/out/assets/plus-4hygj-1Z.js +1 -0
- package/out/assets/{save-BcI68ZgS.js → save-BjrbPwhJ.js} +1 -1
- package/out/assets/search-DSkiWdvX.js +1 -0
- package/out/assets/{send-_ups0_3f.js → send-BL4d5iOt.js} +1 -1
- package/out/assets/{shield-check-Dzw5rdPe.js → shield-check-DzDuWO8r.js} +1 -1
- package/out/assets/{smartphone-DSQ5L_sr.js → smartphone-tRRFFO0a.js} +1 -1
- package/out/assets/{trash-2-BIrBn6Ce.js → trash-2-V12tJ8lI.js} +1 -1
- package/out/assets/triangle-alert-DGWc8ZHu.js +1 -0
- package/out/assets/{ui-u9yJHkb-.js → ui-BpDGD3IR.js} +2 -2
- package/out/assets/{upload-1jmNeGjH.js → upload-CoCptKya.js} +1 -1
- package/out/assets/{useChannelMessages-DNxfCew-.js → useChannelMessages-B6RMaNDH.js} +1 -1
- package/out/assets/{useGameRoom-Du07VEgb.js → useGameRoom-CRJL0kcm.js} +1 -1
- package/out/assets/{userProfile-CL1Ev2GK.js → userProfile-DBkH4s29.js} +1 -1
- package/out/assets/{wallet-BvM_X5nW.js → wallet-T7ONZ3Kg.js} +1 -1
- package/out/assets/{wifi-66t1dsgC.js → wifi-Bgo8eHY0.js} +1 -1
- package/out/chat/index.html +0 -0
- package/out/chat/join/index.html +0 -0
- package/out/download/index.html +2 -2
- package/out/game/gandengyan/index.html +0 -0
- package/out/game/index.html +0 -0
- package/out/game/zhajinhua/index.html +0 -0
- package/out/index.html +2 -2
- package/out/note/index.html +0 -0
- package/out/ping/index.html +2 -2
- package/out/profile/index.html +0 -0
- package/out/web3/index.html +0 -0
- package/package.json +1 -8
- package/server/src/core/releaseManifest.js +1 -18
- package/server/src/index.js +0 -284
- package/out/assets/LanguageToggle-Cfh33R2h.js +0 -1
- package/out/assets/MarketingHeader-BKBngzf5.js +0 -1
- package/out/assets/MarketingLayout-C3xrXmfU.js +0 -1
- package/out/assets/SidebarHomeLink-LzYXrJRr.js +0 -1
- package/out/assets/arrow-right-BC_GWahx.js +0 -1
- package/out/assets/i18n-Cqyi6NZb.js +0 -1
- package/out/assets/index-CSBg7dZN.css +0 -1
- package/out/assets/index-CiHRnvMj.js +0 -31
- package/out/assets/index.lazy-BdOfbfjo.js +0 -2
- package/out/assets/index.lazy-Bo6McUf1.js +0 -1
- package/out/assets/index.lazy-BxUje7fk.js +0 -1
- package/out/assets/index.lazy-CfuoMz6P.js +0 -1
- package/out/assets/index.lazy-DRaxm9OS.js +0 -1
- package/out/assets/index.lazy-DkrwcEBu.js +0 -2
- package/out/assets/index.lazy-K6IB-5kb.js +0 -3
- package/out/assets/index.lazy-Uu9DCtrI.js +0 -1
- package/out/assets/index.lazy-mXESMo49.js +0 -1
- package/out/assets/play-Ds19moWN.js +0 -1
- package/out/assets/plus-CvGkRhJV.js +0 -1
- package/out/assets/search-BIa4RSPA.js +0 -1
- package/out/assets/triangle-alert-CgWIEl4u.js +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "most-box",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
4
4
|
"description": "MostBox - P2P file sharing application",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "electron/main.js",
|
|
@@ -164,13 +164,6 @@
|
|
|
164
164
|
"x64",
|
|
165
165
|
"arm64"
|
|
166
166
|
]
|
|
167
|
-
},
|
|
168
|
-
{
|
|
169
|
-
"target": "zip",
|
|
170
|
-
"arch": [
|
|
171
|
-
"x64",
|
|
172
|
-
"arm64"
|
|
173
|
-
]
|
|
174
167
|
}
|
|
175
168
|
],
|
|
176
169
|
"icon": "public/logo-512.png",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const RELEASE_PLATFORMS = ['windows', 'macos', 'linux']
|
|
2
2
|
export const RELEASE_ARCHES = ['x64', 'arm64']
|
|
3
|
-
export const RELEASE_ASSET_KINDS = ['installer'
|
|
3
|
+
export const RELEASE_ASSET_KINDS = ['installer']
|
|
4
4
|
|
|
5
5
|
export const RELEASE_TARGETS = Object.freeze([
|
|
6
6
|
{ platform: 'windows', arch: 'x64' },
|
|
@@ -89,20 +89,3 @@ export function resolveReleaseAssetDownload(asset, preferredSource = 'r2') {
|
|
|
89
89
|
: '',
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
|
-
|
|
93
|
-
export function findCompatibleUpdateAsset(manifest, platform, arch) {
|
|
94
|
-
if (!isReleaseManifest(manifest)) return null
|
|
95
|
-
|
|
96
|
-
const compatibleAssets = manifest.assets.filter(
|
|
97
|
-
asset =>
|
|
98
|
-
asset.platform === platform &&
|
|
99
|
-
asset.arch === arch &&
|
|
100
|
-
(asset.kind === 'updater' || asset.kind === 'installer')
|
|
101
|
-
)
|
|
102
|
-
|
|
103
|
-
return (
|
|
104
|
-
compatibleAssets.find(asset => asset.kind === 'updater') ||
|
|
105
|
-
compatibleAssets.find(asset => asset.kind === 'installer') ||
|
|
106
|
-
null
|
|
107
|
-
)
|
|
108
|
-
}
|
package/server/src/index.js
CHANGED
|
@@ -1940,290 +1940,6 @@ export class MostBoxEngine extends EventEmitter {
|
|
|
1940
1940
|
return result
|
|
1941
1941
|
}
|
|
1942
1942
|
|
|
1943
|
-
/**
|
|
1944
|
-
* 按 CID 将内容下载到指定路径,不写入用户文件列表。
|
|
1945
|
-
* 用于桌面客户端更新等内部缓存场景。
|
|
1946
|
-
* @param {object} input - 下载参数
|
|
1947
|
-
* @param {string} input.cid - 文件 CID
|
|
1948
|
-
* @param {string} input.targetPath - 目标文件路径
|
|
1949
|
-
* @param {string} [input.fileName] - 持有记录展示名
|
|
1950
|
-
* @param {string} [input.taskId] - 下载任务 ID
|
|
1951
|
-
* @param {number} [input.timeout] - 等待 P2P 内容的超时时间
|
|
1952
|
-
* @param {number} [input.streamReadTimeout] - 下载流无进度超时时间
|
|
1953
|
-
* @param {boolean} [input.overwrite=true] - 是否覆盖已存在目标文件
|
|
1954
|
-
* @param {string} [input.source='update'] - holding 来源
|
|
1955
|
-
*/
|
|
1956
|
-
async downloadCidToPath(input = {}) {
|
|
1957
|
-
this.#ensureInitialized()
|
|
1958
|
-
|
|
1959
|
-
const cid = input.cid
|
|
1960
|
-
const targetPath = input.targetPath
|
|
1961
|
-
if (!cid) throw new ValidationError('cid is required')
|
|
1962
|
-
if (!targetPath) throw new ValidationError('targetPath is required')
|
|
1963
|
-
|
|
1964
|
-
this.#getCidInfo(cid)
|
|
1965
|
-
const taskId =
|
|
1966
|
-
input.taskId || `cid_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
|
|
1967
|
-
const taskState = { aborted: false, readStream: null, writeStream: null }
|
|
1968
|
-
const timeout = input.timeout || this.#options.downloadTimeout
|
|
1969
|
-
const streamReadTimeout =
|
|
1970
|
-
input.streamReadTimeout ?? STREAM_READ_TIMEOUT
|
|
1971
|
-
const fileName = sanitizeFilename(input.fileName || path.basename(targetPath))
|
|
1972
|
-
const overwrite = input.overwrite !== false
|
|
1973
|
-
const resolvedTargetPath = path.resolve(targetPath)
|
|
1974
|
-
const targetDir = path.dirname(resolvedTargetPath)
|
|
1975
|
-
const tempPath = `${resolvedTargetPath}.part`
|
|
1976
|
-
|
|
1977
|
-
this.#activeDownloads.set(taskId, taskState)
|
|
1978
|
-
|
|
1979
|
-
try {
|
|
1980
|
-
const writableCheck = await checkDirectoryWritable(targetDir)
|
|
1981
|
-
if (!writableCheck.writable) {
|
|
1982
|
-
throw new PermissionError(writableCheck.error)
|
|
1983
|
-
}
|
|
1984
|
-
if (!overwrite && fs.existsSync(resolvedTargetPath)) {
|
|
1985
|
-
throw new ConflictError(`File already exists: ${resolvedTargetPath}`)
|
|
1986
|
-
}
|
|
1987
|
-
fs.rmSync(tempPath, { force: true })
|
|
1988
|
-
|
|
1989
|
-
const { driveName } = this.#getCidInfo(cid)
|
|
1990
|
-
let drive = this.#drives.get(driveName)
|
|
1991
|
-
if (!drive) {
|
|
1992
|
-
drive = await this.#getOrCreateDrive(driveName, {
|
|
1993
|
-
server: true,
|
|
1994
|
-
client: true,
|
|
1995
|
-
})
|
|
1996
|
-
this.emit('download:status', { taskId, status: 'connecting' })
|
|
1997
|
-
}
|
|
1998
|
-
|
|
1999
|
-
await this.#joinCidTopicInternal(cid, {
|
|
2000
|
-
server: false,
|
|
2001
|
-
client: true,
|
|
2002
|
-
})
|
|
2003
|
-
|
|
2004
|
-
if (taskState.aborted) throw new Error('Download cancelled')
|
|
2005
|
-
this.emit('download:status', { taskId, status: 'finding-peers' })
|
|
2006
|
-
|
|
2007
|
-
const driveKey = '/' + cid
|
|
2008
|
-
const entry = await this.#waitForDriveEntry(
|
|
2009
|
-
drive,
|
|
2010
|
-
driveKey,
|
|
2011
|
-
timeout,
|
|
2012
|
-
taskId,
|
|
2013
|
-
taskState
|
|
2014
|
-
)
|
|
2015
|
-
|
|
2016
|
-
if (!entry) {
|
|
2017
|
-
throw new PeerNotFoundError(
|
|
2018
|
-
'当前没有发现可下载的在线种子,请稍后重试或确认发布者在线'
|
|
2019
|
-
)
|
|
2020
|
-
}
|
|
2021
|
-
|
|
2022
|
-
let totalBytes = 0
|
|
2023
|
-
try {
|
|
2024
|
-
const stat = await drive.entry(entry.key)
|
|
2025
|
-
totalBytes = Number(stat?.value?.blob?.byteLength) || 0
|
|
2026
|
-
} catch {}
|
|
2027
|
-
|
|
2028
|
-
this.emit('download:status', {
|
|
2029
|
-
taskId,
|
|
2030
|
-
status: 'downloading',
|
|
2031
|
-
file: fileName,
|
|
2032
|
-
size: totalBytes ? formatFileSize(totalBytes) : null,
|
|
2033
|
-
})
|
|
2034
|
-
|
|
2035
|
-
const rs = drive.createReadStream(entry.key)
|
|
2036
|
-
const ws = fs.createWriteStream(tempPath)
|
|
2037
|
-
taskState.readStream = rs
|
|
2038
|
-
taskState.writeStream = ws
|
|
2039
|
-
|
|
2040
|
-
let loadedBytes = 0
|
|
2041
|
-
let lastProgressUpdate = 0
|
|
2042
|
-
|
|
2043
|
-
await new Promise((resolve, reject) => {
|
|
2044
|
-
let settled = false
|
|
2045
|
-
let readTimer = null
|
|
2046
|
-
|
|
2047
|
-
const clearReadTimer = () => {
|
|
2048
|
-
if (readTimer) {
|
|
2049
|
-
clearTimeout(readTimer)
|
|
2050
|
-
readTimer = null
|
|
2051
|
-
}
|
|
2052
|
-
}
|
|
2053
|
-
|
|
2054
|
-
const fail = err => {
|
|
2055
|
-
if (settled) return
|
|
2056
|
-
settled = true
|
|
2057
|
-
clearReadTimer()
|
|
2058
|
-
rs.destroy(err)
|
|
2059
|
-
ws.destroy()
|
|
2060
|
-
fs.unlink(tempPath, () => {})
|
|
2061
|
-
reject(err)
|
|
2062
|
-
}
|
|
2063
|
-
|
|
2064
|
-
const complete = () => {
|
|
2065
|
-
if (settled) return
|
|
2066
|
-
settled = true
|
|
2067
|
-
clearReadTimer()
|
|
2068
|
-
resolve()
|
|
2069
|
-
}
|
|
2070
|
-
|
|
2071
|
-
const resetReadTimer = () => {
|
|
2072
|
-
clearReadTimer()
|
|
2073
|
-
if (streamReadTimeout > 0) {
|
|
2074
|
-
readTimer = setTimeout(() => {
|
|
2075
|
-
fail(
|
|
2076
|
-
new Error(
|
|
2077
|
-
`Download stalled: no data received for ${streamReadTimeout / 1000}s`
|
|
2078
|
-
)
|
|
2079
|
-
)
|
|
2080
|
-
}, streamReadTimeout)
|
|
2081
|
-
}
|
|
2082
|
-
}
|
|
2083
|
-
|
|
2084
|
-
resetReadTimer()
|
|
2085
|
-
|
|
2086
|
-
rs.on('data', chunk => {
|
|
2087
|
-
if (taskState.aborted) {
|
|
2088
|
-
fail(new Error('Download cancelled'))
|
|
2089
|
-
return
|
|
2090
|
-
}
|
|
2091
|
-
resetReadTimer()
|
|
2092
|
-
loadedBytes += chunk.length
|
|
2093
|
-
const now = Date.now()
|
|
2094
|
-
if (
|
|
2095
|
-
totalBytes > 0 &&
|
|
2096
|
-
now - lastProgressUpdate > PROGRESS_THROTTLE
|
|
2097
|
-
) {
|
|
2098
|
-
lastProgressUpdate = now
|
|
2099
|
-
this.emit('download:progress', {
|
|
2100
|
-
taskId,
|
|
2101
|
-
loaded: loadedBytes,
|
|
2102
|
-
total: totalBytes,
|
|
2103
|
-
percent: Math.round((loadedBytes / totalBytes) * 100),
|
|
2104
|
-
})
|
|
2105
|
-
}
|
|
2106
|
-
})
|
|
2107
|
-
|
|
2108
|
-
rs.pipe(ws)
|
|
2109
|
-
ws.on('finish', complete)
|
|
2110
|
-
ws.on('error', fail)
|
|
2111
|
-
rs.on('error', fail)
|
|
2112
|
-
rs.on('close', () => {
|
|
2113
|
-
if (taskState.aborted) fail(new Error('Download cancelled'))
|
|
2114
|
-
})
|
|
2115
|
-
ws.on('close', () => {
|
|
2116
|
-
if (taskState.aborted) fail(new Error('Download cancelled'))
|
|
2117
|
-
})
|
|
2118
|
-
})
|
|
2119
|
-
|
|
2120
|
-
if (taskState.aborted) throw new Error('Download cancelled')
|
|
2121
|
-
|
|
2122
|
-
this.emit('download:status', { taskId, status: 'verifying' })
|
|
2123
|
-
const { cid: downloadedCid, size } = await calculateCid(tempPath)
|
|
2124
|
-
if (downloadedCid.toString() !== cid) {
|
|
2125
|
-
fs.unlinkSync(tempPath)
|
|
2126
|
-
throw new IntegrityError(
|
|
2127
|
-
`File content CID mismatch. Expected ${cid}, got ${downloadedCid.toString()}.`
|
|
2128
|
-
)
|
|
2129
|
-
}
|
|
2130
|
-
|
|
2131
|
-
if (fs.existsSync(resolvedTargetPath)) {
|
|
2132
|
-
fs.rmSync(resolvedTargetPath, { force: true })
|
|
2133
|
-
}
|
|
2134
|
-
fs.renameSync(tempPath, resolvedTargetPath)
|
|
2135
|
-
|
|
2136
|
-
await this.seedCidFileFromPath(cid, resolvedTargetPath, {
|
|
2137
|
-
fileName,
|
|
2138
|
-
source: input.source || 'update',
|
|
2139
|
-
})
|
|
2140
|
-
|
|
2141
|
-
const result = {
|
|
2142
|
-
taskId,
|
|
2143
|
-
cid,
|
|
2144
|
-
fileName,
|
|
2145
|
-
savedPath: resolvedTargetPath,
|
|
2146
|
-
size,
|
|
2147
|
-
}
|
|
2148
|
-
this.emit('download:success', result)
|
|
2149
|
-
return result
|
|
2150
|
-
} finally {
|
|
2151
|
-
this.#activeDownloads.delete(taskId)
|
|
2152
|
-
fs.rmSync(tempPath, { force: true })
|
|
2153
|
-
}
|
|
2154
|
-
}
|
|
2155
|
-
|
|
2156
|
-
/**
|
|
2157
|
-
* 将本地文件按既有 CID 写入 Hyperdrive 并记录 holding,不写入用户文件列表。
|
|
2158
|
-
* @param {string} cid - 文件 CID
|
|
2159
|
-
* @param {string} filePath - 本地文件路径
|
|
2160
|
-
* @param {object} [options] - 选项
|
|
2161
|
-
* @param {string} [options.fileName] - 持有记录展示名
|
|
2162
|
-
* @param {string} [options.source='update'] - holding 来源
|
|
2163
|
-
*/
|
|
2164
|
-
async seedCidFileFromPath(cid, filePath, options = {}) {
|
|
2165
|
-
this.#ensureInitialized()
|
|
2166
|
-
if (!cid) throw new ValidationError('cid is required')
|
|
2167
|
-
if (!filePath) throw new ValidationError('filePath is required')
|
|
2168
|
-
|
|
2169
|
-
this.#getCidInfo(cid)
|
|
2170
|
-
const sizeValidation = await validateFileSize(
|
|
2171
|
-
filePath,
|
|
2172
|
-
this.#options.maxFileSize
|
|
2173
|
-
)
|
|
2174
|
-
if (!sizeValidation.valid) {
|
|
2175
|
-
throw new FileSizeError(sizeValidation.error, sizeValidation.size)
|
|
2176
|
-
}
|
|
2177
|
-
|
|
2178
|
-
const { cid: actualCid } = await calculateCid(filePath)
|
|
2179
|
-
const actualCidString = actualCid.toString()
|
|
2180
|
-
if (actualCidString !== cid) {
|
|
2181
|
-
throw new IntegrityError(
|
|
2182
|
-
`File content CID mismatch. Expected ${cid}, got ${actualCidString}.`
|
|
2183
|
-
)
|
|
2184
|
-
}
|
|
2185
|
-
|
|
2186
|
-
const existingHolding = this.#holdings.find(holding => holding.cid === cid)
|
|
2187
|
-
if (!existingHolding) {
|
|
2188
|
-
this.#checkCapacity(sizeValidation.size || 0)
|
|
2189
|
-
}
|
|
2190
|
-
|
|
2191
|
-
const { driveName } = this.#getCidInfo(cid)
|
|
2192
|
-
const drive = await this.#getOrCreateDrive(driveName, {
|
|
2193
|
-
server: true,
|
|
2194
|
-
client: false,
|
|
2195
|
-
})
|
|
2196
|
-
const driveKey = '/' + cid
|
|
2197
|
-
const localContent = await this.#getLocalCidContent(cid, {
|
|
2198
|
-
public: true,
|
|
2199
|
-
allowHoldingFallback: true,
|
|
2200
|
-
})
|
|
2201
|
-
|
|
2202
|
-
if (!localContent) {
|
|
2203
|
-
const readStream = fs.createReadStream(filePath)
|
|
2204
|
-
const writeStream = drive.createWriteStream(driveKey)
|
|
2205
|
-
await new Promise((resolve, reject) => {
|
|
2206
|
-
readStream.pipe(writeStream)
|
|
2207
|
-
writeStream.on('finish', resolve)
|
|
2208
|
-
writeStream.on('error', reject)
|
|
2209
|
-
readStream.on('error', reject)
|
|
2210
|
-
})
|
|
2211
|
-
}
|
|
2212
|
-
|
|
2213
|
-
await this.#joinCidTopicInternal(cid, {
|
|
2214
|
-
server: true,
|
|
2215
|
-
client: false,
|
|
2216
|
-
})
|
|
2217
|
-
|
|
2218
|
-
return this.#upsertHolding({
|
|
2219
|
-
cid,
|
|
2220
|
-
fileName: sanitizeFilename(options.fileName || path.basename(filePath)),
|
|
2221
|
-
size: sizeValidation.size || 0,
|
|
2222
|
-
driveName,
|
|
2223
|
-
source: options.source || 'update',
|
|
2224
|
-
})
|
|
2225
|
-
}
|
|
2226
|
-
|
|
2227
1943
|
/**
|
|
2228
1944
|
* 读取已发布文件的内容(用于预览)
|
|
2229
1945
|
* Hyperdrive 中用 CID 作为 key 存储
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./jsx-runtime-Bt-cYkS5.js";import{s as t,t as n,w as r}from"./ui-u9yJHkb-.js";import{a as i,c as a,o}from"./i18n-Cqyi6NZb.js";var s=r(`check`,[[`path`,{d:`M20 6 9 17l-5-5`,key:`1gmf2c`}]]),c=r(`languages`,[[`path`,{d:`m5 8 6 6`,key:`1wu5hv`}],[`path`,{d:`m4 14 6-6 2-3`,key:`1k1g8d`}],[`path`,{d:`M2 5h12`,key:`or177f`}],[`path`,{d:`M7 2h1`,key:`1t2jsx`}],[`path`,{d:`m22 22-5-10-5 10`,key:`don7ne`}],[`path`,{d:`M14 18h6`,key:`1m8k6r`}]]),l=r(`moon`,[[`path`,{d:`M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401`,key:`kfwtm`}]]),u=r(`refresh-cw`,[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]]),d=r(`sun`,[[`circle`,{cx:`12`,cy:`12`,r:`4`,key:`4exip2`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`m4.93 4.93 1.41 1.41`,key:`149t6j`}],[`path`,{d:`m17.66 17.66 1.41 1.41`,key:`ptbguv`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`m6.34 17.66-1.41 1.41`,key:`1m8zz5`}],[`path`,{d:`m19.07 4.93-1.41 1.41`,key:`1shlcs`}]]),f=e();function p(){let{t:e}=i(),{state:n,installAndRestart:r}=t(),a=n.status===`checking`,o=n.status===`downloading`,s=n.status===`downloaded`,c=n.status===`installing`,l=a||o||c;if(!a&&!o&&!s&&!c)return null;let d=e(`desktopUpdate.install`);a?d=e(`desktopUpdate.checking`):o?d=n.progress>0?e(`desktopUpdate.downloadingProgress`,{progress:n.progress}):e(`desktopUpdate.downloading`):c&&(d=e(`desktopUpdate.installing`));let p=a||o?e(`desktopUpdate.downloadingTitle`):e(`desktopUpdate.readyTitle`,{version:n.version||n.filename});return(0,f.jsxs)(`button`,{type:`button`,className:`btn ${s||c?`btn-primary`:`btn-secondary`} desktop-update-button`,disabled:!s||c,title:p,"aria-live":l?`polite`:void 0,onClick:()=>{s&&r()},children:[(0,f.jsx)(u,{size:16,className:l?`spin`:void 0}),d]})}function m({className:e=``}){let{locale:t,localeName:r,setLocale:l,t:u}=i(),d=u(`common.locale.choose`),p=`${d} (${u(`common.locale.current`)}: ${r})`;return(0,f.jsx)(n,{ariaLabel:d,placement:`bottom-end`,items:o.map(e=>({key:e,label:a[e],icon:e===t?(0,f.jsx)(s,{size:16}):(0,f.jsx)(`span`,{"aria-hidden":`true`}),onSelect:()=>{e!==t&&l(e)}})),renderTrigger:t=>(0,f.jsx)(`button`,{...t,className:[`language-toggle`,e].filter(Boolean).join(` `),"aria-label":d,title:p,children:(0,f.jsx)(c,{size:16})})})}export{l as a,u as i,p as n,s as o,d as r,m as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./jsx-runtime-Bt-cYkS5.js";import{n as t,t as n}from"./LanguageToggle-Cfh33R2h.js";import{I as r,j as i}from"./index-CiHRnvMj.js";import{t as a}from"./MarketingThemeToggle-Cl7PhFgv.js";var o=e();function s(){return(0,o.jsx)(`nav`,{className:`mkt-nav`,children:(0,o.jsxs)(`div`,{className:`mkt-nav-inner`,children:[(0,o.jsxs)(`button`,{type:`button`,className:`mkt-nav-logo`,onClick:i(),children:[(0,o.jsx)(r,{size:18}),(0,o.jsx)(`span`,{children:`MOST PEOPLE`})]}),(0,o.jsxs)(`div`,{className:`mkt-nav-cta`,children:[(0,o.jsx)(a,{}),(0,o.jsx)(n,{className:`mkt-theme-toggle`}),(0,o.jsx)(t,{})]})]})})}export{s as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./jsx-runtime-Bt-cYkS5.js";import{O as t,c as n,o as r}from"./ui-u9yJHkb-.js";import{a as i}from"./i18n-Cqyi6NZb.js";import{n as a,t as o}from"./LanguageToggle-Cfh33R2h.js";import{t as s}from"./download-DPA-3LpR.js";import{i as c}from"./index-CiHRnvMj.js";import{t as l}from"./MarketingThemeToggle-Cl7PhFgv.js";import{t as u}from"./LogoIcon-B2fFe0l1.js";var d={name:`most-box`,version:`0.2.7`,description:`MostBox - P2P file sharing application`,type:`module`,main:`electron/main.js`,bin:{"most-box":`server/cli.js`},files:[`out`,`public`,`electron`,`server/src`,`server/index.js`,`server/cli.js`],scripts:{start:`vite`,server:`node --watch server/index.js`,dev:`vite`,build:`vite build && node scripts/prepare-start-static.mjs`,preview:`vite preview`,serve:`npm run build && node server/index.js`,test:`node --test server/tests/**/*.test.js`,"test:unit":`node --test server/tests/unit/*.test.js`,"test:desktop":`node --test electron/*.test.js`,"test:frontend":`node --test src/tests/*.test.js`,"test:protocol":`node --test --test-name-pattern "extracts CID and filename|matches golden CID samples|publishes a file from Buffer|lists published files|pulls through local seed nodes" server/tests/unit/cid.test.js server/tests/integration/cid.test.js server/tests/integration/engine.test.js`,android:`npm --prefix mobile/android start`,"android:build":`npm --prefix mobile/android run apk`,"android:test":`npm --prefix mobile/android test`,typecheck:`tsc -p tsconfig.typecheck.json`,"typecheck:strict-router":`tsc -p tsconfig.strict-router.json`,"check:static-output":`node scripts/check-static-output.mjs`,format:`npx prettier --write .`,lint:`npx eslint .`,"r2:cors":`node scripts/configure-r2-cors.mjs`,"electron:dev":`concurrently "npm run build" "wait-on out/index.html && electron ."`,"electron:rebuild":`electron-rebuild -f -w sodium-native`,"electron:build":`npm run build && npm run electron:rebuild && electron-builder`,"electron:build:win":`npm run build && npm run electron:rebuild && electron-builder --win`,"electron:build:win:x64":`npm run electron:build:win -- --x64`,"electron:build:win:arm64":`npm run electron:build:win -- --arm64`,"electron:build:mac":`npm run build && npm run electron:rebuild && electron-builder --mac`,"electron:build:linux":`npm run build && npm run electron:rebuild && electron-builder --linux`},keywords:[`p2p`,`file-sharing`,`hyperswarm`,`hyperdrive`],license:`MIT`,dependencies:{"@dicebear/collection":`^9.4.2`,"@dicebear/core":`^9.4.2`,"@hono/node-server":`^2.0.4`,"@tanstack/react-router":`^1.170.15`,"@tanstack/react-start":`^1.168.25`,b4a:`^1.8.1`,busboy:`^1.6.0`,corestore:`^7.10.0`,dayjs:`^1.11.21`,ethers:`^6.16.0`,eventemitter3:`^5.0.4`,hono:`^4.12.23`,hypercore:`^11.33.1`,hyperdrive:`^13.3.2`,hyperswarm:`^4.17.0`,"ipfs-unixfs-importer":`^17.0.1`,multiformats:`^14.0.0`,tweetnacl:`^1.0.3`,ws:`^8.21.0`},devDependencies:{"@electron/rebuild":`^4.0.4`,"@eslint/js":`^10.0.1`,"@iconify/react":`^6.0.2`,"@mantine/hooks":`^9.3.0`,"@milkdown/crepe":`^7.21.2`,"@milkdown/utils":`^7.21.2`,"@types/react":`^19.2.16`,"@vitejs/plugin-react":`^6.0.2`,concurrently:`^10.0.3`,electron:`^42.3.3`,"electron-builder":`^26.8.1`,esbuild:`^0.28.0`,eslint:`^10.4.1`,globals:`^17.6.0`,ky:`^2.0.2`,"lucide-react":`^1.17.0`,prettier:`^3.8.3`,"qrcode.react":`^4.2.0`,react:`^19.2.7`,"react-dom":`^19.2.7`,typescript:`6.0.3`,"typescript-eslint":`^8.60.1`,vite:`^8.0.16`,"wait-on":`^9.0.10`,zustand:`^5.0.14`},overrides:{"brace-expansion":`5.0.6`,postcss:`8.5.15`,ws:`$ws`},build:{appId:`com.mostbox.app`,productName:`MostBox`,publish:[{provider:`github`,releaseType:`release`}],directories:{output:`dist`},afterPack:`electron/afterPack.cjs`,files:[`out/**/*`,`electron/**/*`,`server/src/**/*`,`server/index.js`,`server/cli.js`,`package.json`,`!**/*.map`,`!electron/**/*.test.js`,`!server/tests/**/*`],asarUnpack:[`**/*.node`,`**/sodium-native/**`],protocols:[{name:`MostBox Link`,schemes:[`most`]}],win:{target:[`nsis`],artifactName:"${productName}-${version}-win-${arch}-setup.${ext}",icon:`public/logo.ico`},nsis:{oneClick:!1,allowToChangeInstallationDirectory:!0,createDesktopShortcut:!0,createStartMenuShortcut:!0,shortcutName:`MostBox`},mac:{artifactName:"${productName}-${version}-mac-${arch}.${ext}",target:[{target:`dmg`,arch:[`x64`,`arm64`]},{target:`zip`,arch:[`x64`,`arm64`]}],icon:`public/logo-512.png`,category:`public.app-category.utilities`},dmg:{contents:[{x:130,y:220},{x:410,y:220,type:`link`,path:`/Applications`}]},linux:{artifactName:"${productName}-${version}-linux-${arch}.${ext}",target:[{target:`AppImage`,arch:[`x64`,`arm64`]}],icon:`public/logo-512.png`,category:`Utility`}}},f=e(),p=[{to:`/`,labelKey:`footer.about`},{to:`/ping/`,labelKey:`footer.network`},{href:`https://github.com/most-people/most`,labelKey:null,label:`GitHub`,external:!0}],m=d.version;function h(){let{t:e}=i();return(0,f.jsx)(`footer`,{className:`mkt-footer`,children:(0,f.jsx)(`div`,{className:`mkt-container`,children:(0,f.jsxs)(`div`,{className:`mkt-footer-inner`,children:[(0,f.jsx)(`div`,{className:`mkt-footer-links`,children:p.map(n=>`external`in n?(0,f.jsx)(`a`,{href:n.href,target:`_blank`,rel:`noopener noreferrer`,children:n.label},n.href):(0,f.jsx)(t,{to:n.to,children:e(n.labelKey)},n.to))}),(0,f.jsxs)(`span`,{className:`mkt-footer-copy`,children:[`© `,new Date().getFullYear(),` MOST PEOPLE · MIT License`]}),(0,f.jsxs)(`span`,{className:`mkt-footer-build`,translate:`no`,children:[`v`,m]})]})})})}function g({children:e,header:t}){return(0,f.jsxs)(`div`,{className:`mkt-layout`,children:[t??(0,f.jsx)(_,{}),(0,f.jsx)(`main`,{className:`mkt-layout-main`,children:e}),(0,f.jsx)(h,{})]})}function _(){let e=n(e=>e.identity),d=n(e=>e.openLoginModal),{t:p}=i(),m=r(),h=e?.displayName||e?.username||p(`nav.openWeb`);return(0,f.jsx)(`nav`,{className:`mkt-nav`,children:(0,f.jsxs)(`div`,{className:`mkt-nav-inner`,children:[(0,f.jsxs)(t,{to:`/`,className:`mkt-nav-logo`,children:[(0,f.jsx)(u,{}),`MOST PEOPLE`]}),(0,f.jsxs)(`div`,{className:`mkt-nav-cta`,children:[(0,f.jsx)(l,{}),(0,f.jsx)(o,{className:`mkt-theme-toggle`}),(0,f.jsx)(a,{}),!m&&(0,f.jsxs)(t,{to:`/download/`,className:`btn btn-primary mkt-nav-preview`,children:[(0,f.jsx)(s,{size:16}),p(`nav.downloadClient`)]}),e?(0,f.jsx)(t,{to:`/profile/`,className:`mkt-nav-avatar-trigger`,"aria-label":p(`nav.profile`),title:h,children:(0,f.jsx)(`img`,{className:`mkt-nav-avatar`,src:c(e.address,e.avatar),alt:``,"aria-hidden":`true`})}):(0,f.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:d,children:p(`nav.getStarted`)})]})]})})}export{g as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e,o as t,t as n}from"./jsx-runtime-Bt-cYkS5.js";import{O as r,w as i}from"./ui-u9yJHkb-.js";import{a}from"./i18n-Cqyi6NZb.js";import{n as o,t as s}from"./LanguageToggle-Cfh33R2h.js";import{I as c}from"./index-CiHRnvMj.js";var l=i(`menu`,[[`path`,{d:`M4 5h16`,key:`1tepv9`}],[`path`,{d:`M4 12h16`,key:`1lakjw`}],[`path`,{d:`M4 19h16`,key:`1djgab`}]]),u=t(e(),1);function d(e,t){return typeof t==`boolean`?t:typeof window<`u`&&`matchMedia`in window?window.matchMedia(e).matches:!1}function f(e,t,{getInitialValueInEffect:n}={getInitialValueInEffect:!0}){let[r,i]=(0,u.useState)(n?t:d(e));return(0,u.useEffect)(()=>{try{if(`matchMedia`in window){let t=window.matchMedia(e);i(t.matches);let n=e=>i(e.matches);return t.addEventListener(`change`,n),()=>{t.removeEventListener(`change`,n)}}}catch{return}},[e]),r||!1}function p(e=!1,t={}){let[n,r]=(0,u.useState)(e),i=(0,u.useCallback)(()=>{r(e=>e||(t.onOpen?.(),!0))},[t.onOpen]),a=(0,u.useCallback)(()=>{r(e=>e&&(t.onClose?.(),!1))},[t.onClose]);return[n,{open:i,close:a,toggle:(0,u.useCallback)(()=>{n?a():i()},[a,i,n]),set:r}]}var m=n(),h=(0,u.createContext)(null);function g(){let e=(0,u.useContext)(h);if(!e)throw Error(`useAppShell must be used within AppShell`);return e}function _({sidebar:e,className:t=``,headerTitle:n,headerRight:r,sidebarToggleReplacement:i,defaultHide:c=!1,children:d}){let[g,_]=p(!1),[v,y]=(0,u.useState)(c),b=(0,u.useRef)(c),x=f(`(max-width: 768px)`),{t:S}=a(),C=(0,u.useCallback)((e={})=>{_.close(),e.collapse&&y(!0)},[_]);(0,u.useEffect)(()=>{c!==b.current&&(c?C({collapse:!0}):y(!1),b.current=c)},[c,C]);let w=()=>{x?_.toggle():y(!v)},T=()=>{x?_.open():y(!1)},E=x?g:!v;return(0,m.jsx)(h.Provider,{value:{closeSidebar:C,openSidebar:T,isSidebarVisible:E},children:(0,m.jsxs)(`div`,{className:[`app-layout`,t].filter(Boolean).join(` `),children:[(0,m.jsx)(`div`,{className:`sidebar-overlay ${g?`visible`:``}`,onClick:()=>C()}),(0,m.jsx)(`div`,{className:`sidebar ${g?`open`:``} ${v?`collapsed`:``}`,children:e({closeSidebar:C,openSidebar:T})}),(0,m.jsxs)(`div`,{className:`main-content`,children:[(0,m.jsxs)(`header`,{className:`app-header`,children:[(0,m.jsxs)(`div`,{className:`header-left`,children:[i??(0,m.jsx)(`button`,{onClick:w,className:`btn btn-icon sidebar-toggle-btn`,"aria-label":S(x?`appShell.openMenu`:v?`appShell.expandSidebar`:`appShell.collapseSidebar`),children:(0,m.jsx)(l,{size:16})}),n]}),(0,m.jsxs)(`div`,{className:`header-right`,children:[(0,m.jsx)(o,{}),(0,m.jsx)(s,{className:`btn btn-icon app-language-toggle`}),r]})]}),d]})]})})}function v({onNavigate:e}){let{t}=a(),n=t(`common.brand`);return(0,m.jsxs)(r,{to:`/`,className:`sidebar-header sidebar-header-link`,onClick:e,"aria-label":n,title:n,children:[(0,m.jsx)(c,{size:18}),(0,m.jsx)(`h1`,{children:n})]})}export{p as i,_ as n,g as r,v as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{w as e}from"./ui-u9yJHkb-.js";var t=e(`arrow-right`,[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`m12 5 7 7-7 7`,key:`xquz4c`}]]);export{t};
|