Toggle navigation
Toggle navigation
This project
Loading...
Sign in
digsig
/
bsync-client
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
Stefan Huber
2017-03-08 09:48:26 +0100
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
6fb2e37872a03b26efba1a36005ce38cce3c83c5
6fb2e378
1 parent
fab0481a
last update
Show whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
1338 additions
and
388 deletions
README.md
config/rollup.config.browser-test.js
config/rollup.config.browser.js
config/rollup.config.cordova-test.js
dist/browser-build.js
dist/browser-build.js.map
dist/node-build.js
dist/node-build.js.map
index.d.ts
package.json
scripts/after-test.sh
scripts/before-test.sh
scripts/prepare-cordova-test.sh
spec/browser-test.ts
spec/cordova-plugin-test/plugin.xml
spec/cordova-test.ts
spec/file-handler/test-file-handler.ts
spec/node-test.ts
spec/test/file-handler/node-file-handler.ts
spec/test/file-replicator.ts
spec/test/util.ts
src/api/file-handler.ts
src/browser-main.ts
src/config.ts
src/file-handler/cordova-file-handler.ts
src/file-handler/electron-file-handler.ts
src/file-handler/node-file-handler.ts
src/file-replicator.ts
src/node-main.ts
src/service-locator.ts
src/util.ts
README.md
View file @
6fb2e37
...
...
@@ -4,21 +4,64 @@ Allows downloading of files referenced by a http/https URI inside a couchdb/pouc
# Usage
##
# In cordova projects
##
Use it with pouchdb
### In electron projects
```
typescript
import
{
ServiceLocator
}
from
'bsync-client/dist/browser-build'
;
Within the main process bsync needs to be integrated an initiated.
ServiceLocator
.
getConfig
().
setConfig
(
'itemKey'
,
'type'
);
ServiceLocator
.
getConfig
().
setConfig
(
'itemValue'
,
'asset'
);
import {Bsync} from 'bsync'
;
Bsync.init(ipcMain, filePath
);
let
localDb
=
new
PouchDB
(
'local-pouch-db'
)
;
let
fileReplicator
=
ServiceLocator
.
getFileReplicator
(
);
# Testing (Browser)
localDb
.
put
({
_id
:
"_design/index_type"
,
views
:
{
type
:
{
map
:
function
(
doc
)
{
if
(
doc
[
fileReplicator
.
itemKey
])
{
emit
(
doc
[
fileReplicator
.
itemKey
]);
}
}.
toString
()
}
}
});
fileReplicator
.
once
(
'complete'
,
()
=>
{
// All file are downloaded
});
db
.
query
(
'index_type/type'
,{
include_docs
:
true
,
key
:
fileReplicator
.
itemValue
}).
then
((
res
)
=>
{
let
docs
=
{
docs
:
[]
};
for
(
let
r
of
res
.
rows
)
{
docs
.
docs
.
push
(
r
.
doc
);
}
fileReplicator
.
pushChanges
(
docs
);
fileReplicator
.
start
();
});
```
## In electron projects
Within the
`main process`
bsync needs to be integrated an initiated.
```
typescript
import
{
Bsync
}
from
'bsync'
;
Bsync
.
init
(
ipcMain
,
filePath
);
```
# Testing (Browser/Node)
`npm test`
# Testing (Cordova)
`npm run test:cordova`
...
...
config/rollup.config.browser-test.js
View file @
6fb2e37
...
...
@@ -8,10 +8,6 @@ export default {
format
:
'umd'
,
globals
:
{
'rxjs'
:
'Rx'
},
plugins
:
[
typescript
()
,
globals
(),
...
...
config/rollup.config.browser.js
View file @
6fb2e37
...
...
@@ -9,13 +9,13 @@ export default {
entry
:
'./src/browser-main.ts'
,
dest
:
'./dist/browser-build.js'
,
format
:
'
cjs
'
,
format
:
'
umd
'
,
sourceMap
:
true
,
plugins
:
[
typescript
(),
//
globals(),
//
builtins()
globals
(),
builtins
()
]
};
\ No newline at end of file
...
...
config/rollup.config.cordova-test.js
View file @
6fb2e37
import
typescript
from
'rollup-plugin-typescript'
;
import
builtins
from
'rollup-plugin-node-builtins'
;
import
globals
from
'rollup-plugin-node-globals'
;
export
default
{
...
...
@@ -10,6 +12,8 @@ export default {
format
:
'cjs'
,
plugins
:
[
typescript
()
typescript
(),
globals
(),
builtins
()
]
};
\ No newline at end of file
...
...
dist/browser-build.js
View file @
6fb2e37
'use strict'
;
(
function
(
global
,
factory
)
{
typeof
exports
===
'object'
&&
typeof
module
!==
'undefined'
?
factory
(
exports
)
:
typeof
define
===
'function'
&&
define
.
amd
?
define
([
'exports'
],
factory
)
:
(
factory
((
global
.
bsync
=
global
.
bsync
||
{})));
}(
this
,
(
function
(
exports
)
{
'use strict'
;
Object
.
defineProperty
(
exports
,
'__esModule'
,
{
value
:
true
});
var
domain
;
// This constructor is used to store event handlers. Instantiating this is
// faster than explicitly calling `Object.create(null)` to get a "clean" empty
// object (tested with v8 v4.9).
function
EventHandlers
()
{}
EventHandlers
.
prototype
=
Object
.
create
(
null
);
function
EventEmitter
()
{
EventEmitter
.
init
.
call
(
this
);
}
EventEmitter
.
usingDomains
=
false
;
EventEmitter
.
prototype
.
domain
=
undefined
;
EventEmitter
.
prototype
.
_events
=
undefined
;
EventEmitter
.
prototype
.
_maxListeners
=
undefined
;
// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
EventEmitter
.
defaultMaxListeners
=
10
;
EventEmitter
.
init
=
function
()
{
this
.
domain
=
null
;
if
(
EventEmitter
.
usingDomains
)
{
// if there is an active domain, then attach to it.
if
(
domain
.
active
&&
!
(
this
instanceof
domain
.
Domain
))
{
this
.
domain
=
domain
.
active
;
}
}
if
(
!
this
.
_events
||
this
.
_events
===
Object
.
getPrototypeOf
(
this
).
_events
)
{
this
.
_events
=
new
EventHandlers
();
this
.
_eventsCount
=
0
;
}
this
.
_maxListeners
=
this
.
_maxListeners
||
undefined
;
};
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter
.
prototype
.
setMaxListeners
=
function
setMaxListeners
(
n
)
{
if
(
typeof
n
!==
'number'
||
n
<
0
||
isNaN
(
n
))
throw
new
TypeError
(
'"n" argument must be a positive number'
);
this
.
_maxListeners
=
n
;
return
this
;
};
function
$getMaxListeners
(
that
)
{
if
(
that
.
_maxListeners
===
undefined
)
return
EventEmitter
.
defaultMaxListeners
;
return
that
.
_maxListeners
;
}
EventEmitter
.
prototype
.
getMaxListeners
=
function
getMaxListeners
()
{
return
$getMaxListeners
(
this
);
};
// These standalone emit* functions are used to optimize calling of event
// handlers for fast cases because emit() itself often has a variable number of
// arguments and can be deoptimized because of that. These functions always have
// the same number of arguments and thus do not get deoptimized, so the code
// inside them can execute faster.
function
emitNone
(
handler
,
isFn
,
self
)
{
if
(
isFn
)
handler
.
call
(
self
);
else
{
var
len
=
handler
.
length
;
var
listeners
=
arrayClone
(
handler
,
len
);
for
(
var
i
=
0
;
i
<
len
;
++
i
)
listeners
[
i
].
call
(
self
);
}
}
function
emitOne
(
handler
,
isFn
,
self
,
arg1
)
{
if
(
isFn
)
handler
.
call
(
self
,
arg1
);
else
{
var
len
=
handler
.
length
;
var
listeners
=
arrayClone
(
handler
,
len
);
for
(
var
i
=
0
;
i
<
len
;
++
i
)
listeners
[
i
].
call
(
self
,
arg1
);
}
}
function
emitTwo
(
handler
,
isFn
,
self
,
arg1
,
arg2
)
{
if
(
isFn
)
handler
.
call
(
self
,
arg1
,
arg2
);
else
{
var
len
=
handler
.
length
;
var
listeners
=
arrayClone
(
handler
,
len
);
for
(
var
i
=
0
;
i
<
len
;
++
i
)
listeners
[
i
].
call
(
self
,
arg1
,
arg2
);
}
}
function
emitThree
(
handler
,
isFn
,
self
,
arg1
,
arg2
,
arg3
)
{
if
(
isFn
)
handler
.
call
(
self
,
arg1
,
arg2
,
arg3
);
else
{
var
len
=
handler
.
length
;
var
listeners
=
arrayClone
(
handler
,
len
);
for
(
var
i
=
0
;
i
<
len
;
++
i
)
listeners
[
i
].
call
(
self
,
arg1
,
arg2
,
arg3
);
}
}
function
emitMany
(
handler
,
isFn
,
self
,
args
)
{
if
(
isFn
)
handler
.
apply
(
self
,
args
);
else
{
var
len
=
handler
.
length
;
var
listeners
=
arrayClone
(
handler
,
len
);
for
(
var
i
=
0
;
i
<
len
;
++
i
)
listeners
[
i
].
apply
(
self
,
args
);
}
}
EventEmitter
.
prototype
.
emit
=
function
emit
(
type
)
{
var
er
,
handler
,
len
,
args
,
i
,
events
,
domain
;
var
needDomainExit
=
false
;
var
doError
=
(
type
===
'error'
);
events
=
this
.
_events
;
if
(
events
)
doError
=
(
doError
&&
events
.
error
==
null
);
else
if
(
!
doError
)
return
false
;
domain
=
this
.
domain
;
// If there is no 'error' event listener then throw.
if
(
doError
)
{
er
=
arguments
[
1
];
if
(
domain
)
{
if
(
!
er
)
er
=
new
Error
(
'Uncaught, unspecified "error" event'
);
er
.
domainEmitter
=
this
;
er
.
domain
=
domain
;
er
.
domainThrown
=
false
;
domain
.
emit
(
'error'
,
er
);
}
else
if
(
er
instanceof
Error
)
{
throw
er
;
// Unhandled 'error' event
}
else
{
// At least give some kind of context to the user
var
err
=
new
Error
(
'Uncaught, unspecified "error" event. ('
+
er
+
')'
);
err
.
context
=
er
;
throw
err
;
}
return
false
;
}
handler
=
events
[
type
];
if
(
!
handler
)
return
false
;
var
isFn
=
typeof
handler
===
'function'
;
len
=
arguments
.
length
;
switch
(
len
)
{
// fast cases
case
1
:
emitNone
(
handler
,
isFn
,
this
);
break
;
case
2
:
emitOne
(
handler
,
isFn
,
this
,
arguments
[
1
]);
break
;
case
3
:
emitTwo
(
handler
,
isFn
,
this
,
arguments
[
1
],
arguments
[
2
]);
break
;
case
4
:
emitThree
(
handler
,
isFn
,
this
,
arguments
[
1
],
arguments
[
2
],
arguments
[
3
]);
break
;
// slower
default
:
args
=
new
Array
(
len
-
1
);
for
(
i
=
1
;
i
<
len
;
i
++
)
args
[
i
-
1
]
=
arguments
[
i
];
emitMany
(
handler
,
isFn
,
this
,
args
);
}
if
(
needDomainExit
)
domain
.
exit
();
return
true
;
};
function
_addListener
(
target
,
type
,
listener
,
prepend
)
{
var
m
;
var
events
;
var
existing
;
if
(
typeof
listener
!==
'function'
)
throw
new
TypeError
(
'"listener" argument must be a function'
);
events
=
target
.
_events
;
if
(
!
events
)
{
events
=
target
.
_events
=
new
EventHandlers
();
target
.
_eventsCount
=
0
;
}
else
{
// To avoid recursion in the case that type === "newListener"! Before
// adding it to the listeners, first emit "newListener".
if
(
events
.
newListener
)
{
target
.
emit
(
'newListener'
,
type
,
listener
.
listener
?
listener
.
listener
:
listener
);
// Re-assign `events` because a newListener handler could have caused the
// this._events to be assigned to a new object
events
=
target
.
_events
;
}
existing
=
events
[
type
];
}
var
events
=
require
(
'events'
);
var
rxjs
=
require
(
'rxjs'
);
if
(
!
existing
)
{
// Optimize the case of one listener. Don't need the extra array object.
existing
=
events
[
type
]
=
listener
;
++
target
.
_eventsCount
;
}
else
{
if
(
typeof
existing
===
'function'
)
{
// Adding the second element, need to change to array.
existing
=
events
[
type
]
=
prepend
?
[
listener
,
existing
]
:
[
existing
,
listener
];
}
else
{
// If we've already got an array, just append.
if
(
prepend
)
{
existing
.
unshift
(
listener
);
}
else
{
existing
.
push
(
listener
);
}
}
// Check for listener leak
if
(
!
existing
.
warned
)
{
m
=
$getMaxListeners
(
target
);
if
(
m
&&
m
>
0
&&
existing
.
length
>
m
)
{
existing
.
warned
=
true
;
var
w
=
new
Error
(
'Possible EventEmitter memory leak detected. '
+
existing
.
length
+
' '
+
type
+
' listeners added. '
+
'Use emitter.setMaxListeners() to increase limit'
);
w
.
name
=
'MaxListenersExceededWarning'
;
w
.
emitter
=
target
;
w
.
type
=
type
;
w
.
count
=
existing
.
length
;
emitWarning
(
w
);
}
}
}
return
target
;
}
function
emitWarning
(
e
)
{
typeof
console
.
warn
===
'function'
?
console
.
warn
(
e
)
:
console
.
log
(
e
);
}
EventEmitter
.
prototype
.
addListener
=
function
addListener
(
type
,
listener
)
{
return
_addListener
(
this
,
type
,
listener
,
false
);
};
EventEmitter
.
prototype
.
on
=
EventEmitter
.
prototype
.
addListener
;
EventEmitter
.
prototype
.
prependListener
=
function
prependListener
(
type
,
listener
)
{
return
_addListener
(
this
,
type
,
listener
,
true
);
};
function
_onceWrap
(
target
,
type
,
listener
)
{
var
fired
=
false
;
function
g
()
{
target
.
removeListener
(
type
,
g
);
if
(
!
fired
)
{
fired
=
true
;
listener
.
apply
(
target
,
arguments
);
}
}
g
.
listener
=
listener
;
return
g
;
}
EventEmitter
.
prototype
.
once
=
function
once
(
type
,
listener
)
{
if
(
typeof
listener
!==
'function'
)
throw
new
TypeError
(
'"listener" argument must be a function'
);
this
.
on
(
type
,
_onceWrap
(
this
,
type
,
listener
));
return
this
;
};
EventEmitter
.
prototype
.
prependOnceListener
=
function
prependOnceListener
(
type
,
listener
)
{
if
(
typeof
listener
!==
'function'
)
throw
new
TypeError
(
'"listener" argument must be a function'
);
this
.
prependListener
(
type
,
_onceWrap
(
this
,
type
,
listener
));
return
this
;
};
// emits a 'removeListener' event iff the listener was removed
EventEmitter
.
prototype
.
removeListener
=
function
removeListener
(
type
,
listener
)
{
var
list
,
events
,
position
,
i
,
originalListener
;
if
(
typeof
listener
!==
'function'
)
throw
new
TypeError
(
'"listener" argument must be a function'
);
events
=
this
.
_events
;
if
(
!
events
)
return
this
;
list
=
events
[
type
];
if
(
!
list
)
return
this
;
if
(
list
===
listener
||
(
list
.
listener
&&
list
.
listener
===
listener
))
{
if
(
--
this
.
_eventsCount
===
0
)
this
.
_events
=
new
EventHandlers
();
else
{
delete
events
[
type
];
if
(
events
.
removeListener
)
this
.
emit
(
'removeListener'
,
type
,
list
.
listener
||
listener
);
}
}
else
if
(
typeof
list
!==
'function'
)
{
position
=
-
1
;
for
(
i
=
list
.
length
;
i
--
>
0
;)
{
if
(
list
[
i
]
===
listener
||
(
list
[
i
].
listener
&&
list
[
i
].
listener
===
listener
))
{
originalListener
=
list
[
i
].
listener
;
position
=
i
;
break
;
}
}
if
(
position
<
0
)
return
this
;
if
(
list
.
length
===
1
)
{
list
[
0
]
=
undefined
;
if
(
--
this
.
_eventsCount
===
0
)
{
this
.
_events
=
new
EventHandlers
();
return
this
;
}
else
{
delete
events
[
type
];
}
}
else
{
spliceOne
(
list
,
position
);
}
if
(
events
.
removeListener
)
this
.
emit
(
'removeListener'
,
type
,
originalListener
||
listener
);
}
return
this
;
};
EventEmitter
.
prototype
.
removeAllListeners
=
function
removeAllListeners
(
type
)
{
var
listeners
,
events
;
events
=
this
.
_events
;
if
(
!
events
)
return
this
;
// not listening for removeListener, no need to emit
if
(
!
events
.
removeListener
)
{
if
(
arguments
.
length
===
0
)
{
this
.
_events
=
new
EventHandlers
();
this
.
_eventsCount
=
0
;
}
else
if
(
events
[
type
])
{
if
(
--
this
.
_eventsCount
===
0
)
this
.
_events
=
new
EventHandlers
();
else
delete
events
[
type
];
}
return
this
;
}
// emit removeListener for all listeners on all events
if
(
arguments
.
length
===
0
)
{
var
keys
=
Object
.
keys
(
events
);
for
(
var
i
=
0
,
key
;
i
<
keys
.
length
;
++
i
)
{
key
=
keys
[
i
];
if
(
key
===
'removeListener'
)
continue
;
this
.
removeAllListeners
(
key
);
}
this
.
removeAllListeners
(
'removeListener'
);
this
.
_events
=
new
EventHandlers
();
this
.
_eventsCount
=
0
;
return
this
;
}
listeners
=
events
[
type
];
if
(
typeof
listeners
===
'function'
)
{
this
.
removeListener
(
type
,
listeners
);
}
else
if
(
listeners
)
{
// LIFO order
do
{
this
.
removeListener
(
type
,
listeners
[
listeners
.
length
-
1
]);
}
while
(
listeners
[
0
]);
}
return
this
;
};
EventEmitter
.
prototype
.
listeners
=
function
listeners
(
type
)
{
var
evlistener
;
var
ret
;
var
events
=
this
.
_events
;
if
(
!
events
)
ret
=
[];
else
{
evlistener
=
events
[
type
];
if
(
!
evlistener
)
ret
=
[];
else
if
(
typeof
evlistener
===
'function'
)
ret
=
[
evlistener
.
listener
||
evlistener
];
else
ret
=
unwrapListeners
(
evlistener
);
}
return
ret
;
};
EventEmitter
.
listenerCount
=
function
(
emitter
,
type
)
{
if
(
typeof
emitter
.
listenerCount
===
'function'
)
{
return
emitter
.
listenerCount
(
type
);
}
else
{
return
listenerCount
.
call
(
emitter
,
type
);
}
};
EventEmitter
.
prototype
.
listenerCount
=
listenerCount
;
function
listenerCount
(
type
)
{
var
events
=
this
.
_events
;
if
(
events
)
{
var
evlistener
=
events
[
type
];
if
(
typeof
evlistener
===
'function'
)
{
return
1
;
}
else
if
(
evlistener
)
{
return
evlistener
.
length
;
}
}
return
0
;
}
EventEmitter
.
prototype
.
eventNames
=
function
eventNames
()
{
return
this
.
_eventsCount
>
0
?
Reflect
.
ownKeys
(
this
.
_events
)
:
[];
};
// About 1.5x faster than the two-arg version of Array#splice().
function
spliceOne
(
list
,
index
)
{
for
(
var
i
=
index
,
k
=
i
+
1
,
n
=
list
.
length
;
k
<
n
;
i
+=
1
,
k
+=
1
)
list
[
i
]
=
list
[
k
];
list
.
pop
();
}
function
arrayClone
(
arr
,
i
)
{
var
copy
=
new
Array
(
i
);
while
(
i
--
)
copy
[
i
]
=
arr
[
i
];
return
copy
;
}
function
unwrapListeners
(
arr
)
{
var
ret
=
new
Array
(
arr
.
length
);
for
(
var
i
=
0
;
i
<
ret
.
length
;
++
i
)
{
ret
[
i
]
=
arr
[
i
].
listener
||
arr
[
i
];
}
return
ret
;
}
function
__extends
(
d
,
b
)
{
for
(
var
p
in
b
)
if
(
b
.
hasOwnProperty
(
p
))
d
[
p
]
=
b
[
p
];
...
...
@@ -11,68 +477,168 @@ function __extends(d, b) {
d
.
prototype
=
b
===
null
?
Object
.
create
(
b
)
:
(
__
.
prototype
=
b
.
prototype
,
new
__
());
}
var
ElectronFileHandler
=
(
function
()
{
var
ElectronFileHandler
=
(
function
(
_super
)
{
__extends
(
ElectronFileHandler
,
_super
);
function
ElectronFileHandler
(
ipcRenderer
)
{
_super
.
call
(
this
);
this
.
ipcRenderer
=
ipcRenderer
;
}
ElectronFileHandler
.
prototype
.
download
=
function
(
source
,
target
)
{
var
_this
=
this
;
return
rxjs
.
Observable
.
create
(
function
(
subscriber
)
{
_this
.
ipcRenderer
.
once
(
'bsync-download-complete'
,
function
()
{
this
.
ipcRenderer
.
once
(
'bsync-download-complete'
,
function
()
{
_this
.
ipcRenderer
.
removeAllListeners
(
'bsync-download-progress'
);
_this
.
ipcRenderer
.
removeAllListeners
(
'bsync-download-error'
);
subscriber
.
complete
(
);
_this
.
emit
(
'complete'
);
});
_
this
.
ipcRenderer
.
on
(
'bsync-download-progress'
,
function
(
progress
)
{
subscriber
.
next
(
progress
);
this
.
ipcRenderer
.
on
(
'bsync-download-progress'
,
function
(
progress
)
{
_this
.
emit
(
'progress'
,
progress
);
});
_
this
.
ipcRenderer
.
once
(
'bsync-download-error'
,
function
(
error
)
{
this
.
ipcRenderer
.
once
(
'bsync-download-error'
,
function
(
error
)
{
_this
.
ipcRenderer
.
removeAllListeners
(
'bsync-download-progress'
);
_this
.
ipcRenderer
.
removeAllListeners
(
'bsync-download-complete'
);
subscriber
.
error
(
error
);
_this
.
emit
(
'error'
,
error
);
});
_
this
.
ipcRenderer
.
send
(
'bsync-download'
,
{
this
.
ipcRenderer
.
send
(
'bsync-download'
,
{
source
:
source
,
target
:
target
});
return
this
;
};
ElectronFileHandler
.
prototype
.
cleanup
=
function
(
files
)
{
var
_this
=
this
;
return
new
Promise
(
function
(
resolve
,
reject
)
{
_this
.
ipcRenderer
.
once
(
'bsync-cleanup-complete'
,
function
()
{
_this
.
emit
(
'cleanup-complete'
);
resolve
();
});
_this
.
ipcRenderer
.
send
(
'bsync-cleanup'
,
files
);
});
};
return
ElectronFileHandler
;
}());
}(
EventEmitter
));
var
CordovaDownloader
=
(
function
()
{
function
CordovaDownloader
()
{
var
Util
=
(
function
()
{
function
Util
()
{
}
CordovaDownloader
.
prototype
.
download
=
function
(
source
,
target
)
{
return
Rx
.
Observable
.
create
(
function
(
subscriber
)
{
if
(
!
window
[
'FileTransfer'
])
{
subscriber
.
error
(
"Cordova FileTransfer object undefined"
);
Util
.
getNameHash
=
function
(
path
)
{
for
(
var
r
=
0
,
i
=
0
;
i
<
path
.
length
;
i
++
)
{
r
=
(
r
<<
5
)
-
r
+
path
.
charCodeAt
(
i
),
r
&=
r
;
}
return
"bsync_"
+
Math
.
abs
(
r
);
};
/**
* index >= 0, localFile is in files
* index < 0, localFile is not in files
*/
Util
.
getFileIndex
=
function
(
files
,
localFile
)
{
for
(
var
i
=
0
;
i
<
files
.
length
;
i
++
)
{
if
(
localFile
==
files
[
i
].
target
)
{
return
i
;
}
}
return
-
1
;
};
Util
.
getFilesForCleanup
=
function
(
files
,
localFiles
)
{
var
filesForCleanup
=
[];
for
(
var
_i
=
0
,
localFiles_1
=
localFiles
;
_i
<
localFiles_1
.
length
;
_i
++
)
{
var
localFile
=
localFiles_1
[
_i
];
var
index
=
-
1
;
index
=
Util
.
getFileIndex
(
files
,
localFile
);
if
(
index
<
0
)
{
filesForCleanup
.
push
(
localFile
);
}
else
{
// splice for performance improvement only
files
.
splice
(
index
,
1
);
}
}
return
filesForCleanup
;
};
return
Util
;
}());
var
CordovaFileHandler
=
(
function
(
_super
)
{
__extends
(
CordovaFileHandler
,
_super
);
function
CordovaFileHandler
()
{
_super
.
apply
(
this
,
arguments
);
}
CordovaFileHandler
.
prototype
.
triggerFileTransfer
=
function
(
source
,
target
)
{
var
_this
=
this
;
var
fileTransfer
=
new
window
[
'FileTransfer'
]();
fileTransfer
.
onprogress
=
function
(
progress
)
{
subscriber
.
next
(
progress
.
loaded
/
progress
.
total
);
_this
.
emit
(
'progress'
,
progress
.
loaded
/
progress
.
total
);
};
fileTransfer
.
download
(
source
,
target
,
function
(
entry
)
{
subscriber
.
complete
(
);
_this
.
emit
(
'complete'
,
entry
);
},
function
(
error
)
{
subscriber
.
error
(
error
);
_this
.
emit
(
'error'
,
error
);
},
true
);
};
CordovaFileHandler
.
prototype
.
download
=
function
(
source
,
target
)
{
var
_this
=
this
;
if
(
!
window
[
'FileTransfer'
])
{
this
.
emit
(
'error'
,
'Cordova FileTransfer object undefined'
);
}
window
[
'resolveLocalFileSystemURL'
](
target
,
function
(
entry
)
{
entry
.
getMetadata
(
function
(
metadata
)
{
if
(
metadata
.
size
>
0
)
{
_this
.
emit
(
'complete'
,
entry
);
}
else
{
// file empty trigger transfer
_this
.
triggerFileTransfer
(
source
,
target
);
}
},
function
()
{
// cannot read metadata trigger transfer
_this
.
triggerFileTransfer
(
source
,
target
);
});
},
function
()
{
// file not found, so download it
_this
.
triggerFileTransfer
(
source
,
target
);
});
return
this
;
};
return
CordovaDownloader
;
}());
var
Util
=
(
function
()
{
function
Util
()
{
CordovaFileHandler
.
prototype
.
cleanup
=
function
(
files
,
basePath
)
{
var
_this
=
this
;
var
filesForCleanup
=
[];
return
new
Promise
(
function
(
resolve
,
reject
)
{
if
(
window
[
'resolveLocalFileSystemURL'
])
{
window
[
'resolveLocalFileSystemURL'
](
basePath
,
function
(
entry
)
{
var
reader
=
entry
.
createReader
();
reader
.
readEntries
(
function
(
entries
)
{
for
(
var
_i
=
0
,
entries_1
=
entries
;
_i
<
entries_1
.
length
;
_i
++
)
{
var
e
=
entries_1
[
_i
];
if
(
e
&&
e
.
isFile
)
{
if
(
Util
.
getFileIndex
(
files
,
e
.
name
)
<
0
)
{
filesForCleanup
.
push
(
e
);
}
}
}
var
index
=
0
;
var
error
=
false
;
var
cleanupError
=
function
(
error
)
{
_this
.
emit
(
'cleanup-error'
,
error
);
reject
();
error
=
true
;
};
var
cleanupNext
=
function
()
{
if
(
index
<
filesForCleanup
.
length
&&
!
error
)
{
filesForCleanup
[
index
].
remove
(
cleanupNext
,
cleanupError
);
index
+=
1
;
}
Util
.
getNameHash
=
function
(
path
)
{
for
(
var
r
=
0
,
i
=
0
;
i
<
path
.
length
;
i
++
)
{
r
=
(
r
<<
5
)
-
r
+
path
.
charCodeAt
(
i
),
r
&=
r
;
else
if
(
!
error
)
{
_this
.
emit
(
'cleanup-complete'
,
filesForCleanup
);
resolve
()
;
}
return
"bsync_"
+
Math
.
abs
(
r
);
};
return
Util
;
}());
cleanupNext
();
},
function
(
error
)
{
_this
.
emit
(
'cleanup-error'
,
error
);
reject
();
});
});
}
});
};
return
CordovaFileHandler
;
}(
EventEmitter
));
var
FileReplicator
=
(
function
(
_super
)
{
__extends
(
FileReplicator
,
_super
);
...
...
@@ -81,11 +647,13 @@ var FileReplicator = (function (_super) {
this
.
_files
=
[];
this
.
_itemValidator
=
null
;
this
.
_fileHandler
=
null
;
this
.
_retryTimeout
=
0
;
this
.
_retryTimeout
=
100
;
this
.
_retries
=
10
;
this
.
_itemKey
=
"type"
;
this
.
_itemValue
=
"asset"
;
this
.
_itemSourceAttribute
=
"source"
;
this
.
_itemTargetAttribute
=
"target"
;
this
.
_targetDirectory
=
""
;
}
Object
.
defineProperty
(
FileReplicator
.
prototype
,
"files"
,
{
get
:
function
()
{
...
...
@@ -95,6 +663,9 @@ var FileReplicator = (function (_super) {
configurable
:
true
});
Object
.
defineProperty
(
FileReplicator
.
prototype
,
"fileHandler"
,
{
get
:
function
()
{
return
this
.
_fileHandler
;
},
set
:
function
(
handler
)
{
this
.
_fileHandler
=
handler
;
},
...
...
@@ -155,26 +726,36 @@ var FileReplicator = (function (_super) {
enumerable
:
true
,
configurable
:
true
});
FileReplicator
.
prototype
.
init
=
function
(
files
)
{
Object
.
defineProperty
(
FileReplicator
.
prototype
,
"targetDirectory"
,
{
get
:
function
()
{
return
this
.
_targetDirectory
;
},
set
:
function
(
targetDirectory
)
{
this
.
_targetDirectory
=
targetDirectory
;
},
enumerable
:
true
,
configurable
:
true
});
FileReplicator
.
prototype
.
clear
=
function
(
files
)
{
if
(
files
===
void
0
)
{
files
=
[];
}
this
.
_files
=
files
;
};
/**
* change from pouchdb replicate
*/
FileReplicator
.
prototype
.
pushChanges
=
function
(
change
)
{
FileReplicator
.
prototype
.
pushChanges
=
function
(
docs
)
{
var
items
=
[];
if
(
change
&&
change
.
docs
&&
change
.
docs
.
length
>
0
)
{
for
(
var
_i
=
0
,
_a
=
change
.
docs
;
_i
<
_a
.
length
;
_i
++
)
{
var
item
=
_a
[
_i
];
if
(
docs
&&
docs
.
length
>
0
)
{
for
(
var
_i
=
0
,
docs_1
=
docs
;
_i
<
docs_1
.
length
;
_i
++
)
{
var
item
=
docs_1
[
_i
];
if
(
item
[
this
.
_itemKey
]
&&
item
[
this
.
_itemKey
]
===
this
.
_itemValue
)
{
items
.
push
(
item
);
}
}
}
var
files
=
this
.
prepareFiles
(
items
);
for
(
var
_
b
=
0
,
files_1
=
files
;
_b
<
files_1
.
length
;
_b
++
)
{
var
file
=
files_1
[
_
b
];
for
(
var
_
a
=
0
,
files_1
=
files
;
_a
<
files_1
.
length
;
_a
++
)
{
var
file
=
files_1
[
_
a
];
this
.
_files
.
push
(
file
);
}
};
...
...
@@ -186,15 +767,19 @@ var FileReplicator = (function (_super) {
}
this
.
emit
(
'start'
,
{
progress
:
0
,
index
:
index
,
length
:
files
.
length
});
fileHandler
.
download
(
files
[
index
].
source
,
files
[
index
].
target
)
.
subscribe
(
function
(
progress
)
{
_this
.
emit
(
'progress'
,
{
progress
:
progress
,
index
:
index
,
length
:
files
.
length
});
},
function
(
error
)
{
_this
.
emit
(
'error'
,
{
progress
:
0
,
index
:
index
,
length
:
files
.
length
,
error
:
error
});
},
function
()
{
_this
.
emit
(
'complete'
,
{
progress
:
100
,
index
:
index
,
length
:
files
.
length
});
.
on
(
'progress'
,
function
(
progress
)
{
_this
.
emit
(
'file-progress'
,
{
progress
:
progress
,
index
:
index
,
length
:
files
.
length
});
})
.
once
(
'error'
,
function
(
error
)
{
_this
.
emit
(
'file-error'
,
{
progress
:
0
,
index
:
index
,
length
:
files
.
length
,
error
:
error
});
fileHandler
.
removeAllListeners
();
})
.
once
(
'complete'
,
function
()
{
_this
.
emit
(
'file-complete'
,
{
progress
:
100
,
index
:
index
,
length
:
files
.
length
});
fileHandler
.
removeAllListeners
();
_this
.
downloadFiles
(
files
,
fileHandler
,
index
+
1
);
});
})
.
download
(
files
[
index
].
source
,
this
.
targetDirectory
+
files
[
index
].
target
);
};
FileReplicator
.
prototype
.
prepareFiles
=
function
(
items
)
{
var
output
=
[];
...
...
@@ -213,41 +798,62 @@ var FileReplicator = (function (_super) {
}
return
output
;
};
FileReplicator
.
prototype
.
start
=
function
()
{
FileReplicator
.
prototype
.
start
=
function
(
retries
)
{
var
_this
=
this
;
this
.
on
(
'complete'
,
function
(
event
)
{
if
(
retries
===
void
0
)
{
retries
=
10
;
}
this
.
_retries
=
retries
;
this
.
on
(
'file-complete'
,
function
(
event
)
{
if
((
event
.
index
+
1
)
>=
event
.
length
)
{
_this
.
replicationFinalized
(
event
.
index
);
}
});
this
.
on
(
'error'
,
function
(
event
)
{
this
.
on
(
'
file-
error'
,
function
(
event
)
{
_this
.
replicationFinalized
(
event
.
index
);
});
if
(
this
.
_fileHandler
&&
this
.
_files
.
length
>
0
)
{
this
.
downloadFiles
(
this
.
_files
,
this
.
_fileHandler
);
}
else
{
this
.
emit
(
'complete'
);
}
};
FileReplicator
.
prototype
.
cleanup
=
function
()
{
var
_this
=
this
;
this
.
fileHandler
.
cleanup
(
this
.
_files
,
this
.
_targetDirectory
)
.
then
(
function
()
{
_this
.
emit
(
'cleanup-complete'
);
}).
catch
(
function
()
{
_this
.
emit
(
'cleanup-error'
);
});
};
FileReplicator
.
prototype
.
replicationFinalized
=
function
(
lastIndex
)
{
var
_this
=
this
;
if
(
lastIndex
+
1
>=
this
.
_files
.
length
)
{
this
.
_files
=
[];
this
.
emit
(
'final'
);
this
.
emit
(
'complete'
);
}
else
if
(
this
.
_retr
yTimeout
>
0
)
{
else
if
(
this
.
_retr
ies
>
0
)
{
this
.
_files
.
splice
(
0
,
lastIndex
);
setTimeout
(
function
()
{
_this
.
_retries
=
-
1
;
_this
.
downloadFiles
(
_this
.
_files
,
_this
.
_fileHandler
);
},
this
.
_retryTimeout
);
}
else
{
this
.
emit
(
'error'
);
}
};
return
FileReplicator
;
}(
events
.
EventEmitter
));
}(
EventEmitter
));
var
CONFIG_ITEM_KEY
=
"itemKey"
;
var
CONFIG_ITEM_VALUE
=
"itemValue"
;
var
CONFIG_ITEM_SOURCE_ATTRIBUTE
=
"itemSourceAttribute"
;
var
CONFIG_ITEM_TARGET_ATTRIBUTE
=
"itemTargetAttribute"
;
var
CONFIG_ITEM_VALIDATOR
=
"itemValidator"
;
var
CONFIG_RETRY_TIMEOUT
=
"retryTimeout"
;
var
CONFIG_FILE_HANDLER
=
"fileHandler"
;
var
CONFIG_TARGET_DIRECTORY
=
"targetDirectory"
;
var
Config
=
(
function
()
{
function
Config
()
{
this
.
config
=
{};
...
...
@@ -263,6 +869,7 @@ var Config = (function () {
};
Config
.
prototype
.
setConfig
=
function
(
key
,
value
)
{
this
.
config
[
key
]
=
value
;
return
this
;
};
return
Config
;
}());
...
...
@@ -300,7 +907,7 @@ var ServiceLocator = (function () {
return
new
ElectronFileHandler
(
window
[
'require'
](
'electron'
).
ipcRenderer
);
}
if
(
environment
===
ENV_CORDOVA
)
{
return
new
Cordova
Download
er
();
return
new
Cordova
FileHandl
er
();
}
return
null
;
};
...
...
@@ -308,6 +915,7 @@ var ServiceLocator = (function () {
if
(
!
ServiceLocator
.
fileReplicator
)
{
ServiceLocator
.
fileReplicator
=
new
FileReplicator
();
ServiceLocator
.
fileReplicator
.
fileHandler
=
ServiceLocator
.
getFileHandler
();
}
if
(
ServiceLocator
.
getConfig
().
hasConfig
(
CONFIG_RETRY_TIMEOUT
))
{
ServiceLocator
.
fileReplicator
.
retryTimeout
=
ServiceLocator
.
getConfig
().
getConfig
(
CONFIG_RETRY_TIMEOUT
);
}
...
...
@@ -323,6 +931,8 @@ var ServiceLocator = (function () {
if
(
ServiceLocator
.
getConfig
().
hasConfig
(
CONFIG_ITEM_TARGET_ATTRIBUTE
))
{
ServiceLocator
.
fileReplicator
.
itemTargetAttribute
=
ServiceLocator
.
getConfig
().
getConfig
(
CONFIG_ITEM_TARGET_ATTRIBUTE
);
}
if
(
ServiceLocator
.
getConfig
().
hasConfig
(
CONFIG_TARGET_DIRECTORY
))
{
ServiceLocator
.
fileReplicator
.
targetDirectory
=
ServiceLocator
.
getConfig
().
getConfig
(
CONFIG_TARGET_DIRECTORY
);
}
return
ServiceLocator
.
fileReplicator
;
};
...
...
@@ -330,61 +940,21 @@ var ServiceLocator = (function () {
return
ServiceLocator
;
}());
function
loadBsyncPlugin
(
PouchDB
)
{
var
pouchReplicate
=
PouchDB
.
replicate
;
PouchDB
.
plugin
(
function
(
PouchDB
)
{
PouchDB
.
replicate
=
function
()
{
var
eventEmitter
=
new
events
.
EventEmitter
();
var
emitter
=
pouchReplicate
.
apply
(
this
,
arguments
);
var
replicator
=
ServiceLocator
.
getFileReplicator
();
var
db
=
arguments
[
1
];
replicator
.
once
(
'final'
,
function
(
event
)
{
eventEmitter
.
emit
(
'complete'
);
eventEmitter
.
removeAllListeners
();
});
replicator
.
on
(
'error'
,
function
(
event
)
{
eventEmitter
.
emit
(
'file-replicator-error'
,
event
);
});
replicator
.
on
(
'complete'
,
function
(
event
)
{
eventEmitter
.
emit
(
'file-replicator-complete'
,
event
);
});
replicator
.
on
(
'progress'
,
function
(
event
)
{
eventEmitter
.
emit
(
'file-replicator-progress'
,
event
);
});
emitter
.
once
(
'change'
,
function
(
info
)
{
eventEmitter
.
emit
(
'change'
,
info
);
});
emitter
.
once
(
'complete'
,
function
(
info
)
{
db
.
query
(
'index_type/type'
,
{
include_docs
:
true
,
key
:
replicator
.
itemValue
}).
then
(
function
(
res
)
{
var
docs
=
{
docs
:
[]
};
for
(
var
_i
=
0
,
_a
=
res
.
rows
;
_i
<
_a
.
length
;
_i
++
)
{
var
r
=
_a
[
_i
];
docs
.
docs
.
push
(
r
.
doc
);
}
replicator
.
pushChanges
(
docs
);
replicator
.
start
();
}).
catch
(
function
(
error
)
{
eventEmitter
.
emit
(
'error'
,
error
);
});
});
emitter
.
once
(
'error'
,
function
(
error
)
{
eventEmitter
.
emit
(
'error'
,
error
);
});
return
eventEmitter
;
};
});
}
if
(
typeof
window
!==
'undefined'
&&
window
[
'PouchDB'
])
{
loadBsyncPlugin
(
window
[
'PouchDB'
]);
}
exports
.
loadBsyncPlugin
=
loadBsyncPlugin
;
exports
.
ENV_ELECTRON
=
ENV_ELECTRON
;
exports
.
ENV_CORDOVA
=
ENV_CORDOVA
;
exports
.
ENV_UNKNOWN
=
ENV_UNKNOWN
;
exports
.
ServiceLocator
=
ServiceLocator
;
exports
.
CONFIG_ITEM_KEY
=
CONFIG_ITEM_KEY
;
exports
.
CONFIG_ITEM_VALUE
=
CONFIG_ITEM_VALUE
;
exports
.
CONFIG_ITEM_SOURCE_ATTRIBUTE
=
CONFIG_ITEM_SOURCE_ATTRIBUTE
;
exports
.
CONFIG_ITEM_TARGET_ATTRIBUTE
=
CONFIG_ITEM_TARGET_ATTRIBUTE
;
exports
.
CONFIG_ITEM_VALIDATOR
=
CONFIG_ITEM_VALIDATOR
;
exports
.
CONFIG_RETRY_TIMEOUT
=
CONFIG_RETRY_TIMEOUT
;
exports
.
CONFIG_FILE_HANDLER
=
CONFIG_FILE_HANDLER
;
exports
.
CONFIG_TARGET_DIRECTORY
=
CONFIG_TARGET_DIRECTORY
;
exports
.
Config
=
Config
;
Object
.
defineProperty
(
exports
,
'__esModule'
,
{
value
:
true
});
})));
//# sourceMappingURL=browser-build.js.map
...
...
dist/browser-build.js.map
View file @
6fb2e37
{
"version"
:
3
,
"file"
:
null
,
"sources"
:[
"../src/file-handler/electron-file-handler.ts"
,
"../src/file-handler/cordova-file-handler.ts"
,
"../src/util.ts"
,
"../src/file-replicator.ts"
,
"../src/config.ts"
,
"../src/service-locator.ts"
,
"../src/browser-main.ts"
],
"sourcesContent"
:[
"import { Observable, Subscriber } from 'rxjs';\nimport { FileHandler } from '../api/file-handler';\n\nexport class ElectronFileHandler implements FileHandler {\n\n constructor (private ipcRenderer:any) {\n }\n\n download(source:string, target:string) : Observable<number> {\n return Observable.create((subscriber:Subscriber<number>) => {\n\n this.ipcRenderer.once('bsync-download-complete', () => {\n this.ipcRenderer.removeAllListeners('bsync-download-progress');\n this.ipcRenderer.removeAllListeners('bsync-download-error');\n subscriber.complete();\n });\n\n this.ipcRenderer.on('bsync-download-progress', (progress:number) => {\n subscriber.next(progress);\n });\n\n this.ipcRenderer.once('bsync-download-error', (error:any) => {\n this.ipcRenderer.removeAllListeners('bsync-download-progress');\n this.ipcRenderer.removeAllListeners('bsync-download-complete');\n subscriber.error(error);\n });\n\n this.ipcRenderer.send('bsync-download', {\n source : source ,\n target : target\n });\n });\n }\n\n}"
,
"import { FileHandler } from '../api/file-handler';\n\ndeclare var Rx;\n\nexport class CordovaDownloader implements FileHandler {\n\n download(source:string, target:string) : Rx.Observable<number> {\n return Rx.Observable.create((subscriber:Rx.Subscriber<number>) => {\n\n if (!window['FileTransfer']) {\n subscriber.error(\"Cordova FileTransfer object undefined\");\n }\n\n let fileTransfer = new window['FileTransfer']();\n\n fileTransfer.onprogress = (progress:ProgressEvent) => {\n subscriber.next(progress.loaded / progress.total);\n };\n\n fileTransfer.download(\n source ,\n target ,\n (entry:any) => {\n subscriber.complete();\n } ,\n (error:any) => {\n subscriber.error(error);\n },\n true\n );\n\n }); \n }\n\n}"
,
"export class Util {\n\n static getNameHash(path:string) {\n for(var r=0,i=0;i<path.length;i++) {\n r=(r<<5)-r+path.charCodeAt(i),r&=r;\n }\n return \"bsync_\" + Math.abs(r);\n }\n\n}"
,
"import {FileHandler} from './api/file-handler';\nimport {File} from './api/file';\nimport {Util} from './util';\nimport {EventEmitter} from 'events';\n\nexport class FileReplicator extends EventEmitter {\n\n constructor() {\n super();\n }\n\n protected _files:Array<File> = [];\n\n protected _itemValidator: (item:any) => boolean = null; \n protected _fileHandler:FileHandler = null; \n protected _retryTimeout:number = 0;\n \n protected _itemKey = \"type\";\n protected _itemValue = \"asset\";\n protected _itemSourceAttribute = \"source\";\n protected _itemTargetAttribute = \"target\";\n\n get files(): Array<File> {\n return this._files;\n }\n\n set fileHandler (handler:FileHandler) {\n this._fileHandler = handler;\n }\n\n set retryTimeout (timeout:number) {\n this._retryTimeout = timeout;\n }\n\n set itemValidator(validator:(item:any) => boolean) {\n this._itemValidator = validator;\n }\n\n set itemKey(key:string) {\n this._itemKey = key;\n }\n\n set itemValue(value:string) {\n this._itemValue = value;\n }\n\n set itemSourceAttribute(sourceAttribute:string) {\n this._itemSourceAttribute = sourceAttribute;\n }\n\n set itemTargetAttribute(targetAttribute:string) {\n this._itemTargetAttribute = targetAttribute;\n }\n\n get itemKey() {\n return this._itemKey;\n }\n\n get itemValue() {\n return this._itemValue;\n }\n\n get itemSourceAttribute() {\n return this._itemSourceAttribute;\n }\n\n get itemTargetAttribute() {\n return this._itemTargetAttribute;\n }\n\n init(files: Array<File> = []) {\n this._files = files;\n }\n\n /**\n * change from pouchdb replicate\n */\n pushChanges(change:any) {\n let items:Array<any> = [];\n\n if (change && change.docs && change.docs.length > 0) {\n for (let item of change.docs) {\n if (item[this._itemKey] && item[this._itemKey] === this._itemValue) {\n items.push(item);\n }\n }\n }\n \n let files = this.prepareFiles(items);\n\n for (let file of files) {\n this._files.push(file);\n }\n }\n\n downloadFiles(files:Array<File>, fileHandler:FileHandler, index:number = 0) { \n if (index >= files.length) {\n return;\n }\n\n this.emit('start', { progress: 0, index : index, length : files.length });\n\n fileHandler\n .download(files[index].source, files[index].target)\n .subscribe(\n progress => {\n this.emit('progress', { progress : progress, index : index, length : files.length })\n } ,\n error => {\n this.emit('error', { progress : 0, index : index, length : files.length, error: error });\n } ,\n () => {\n this.emit('complete', { progress : 100 , index : index, length : files.length });\n this.downloadFiles(files, fileHandler, index+1);\n }\n );\n }\n\n prepareFiles(items: Array<any>) : Array<File> {\n let output = [];\n\n for (let item of items) {\n if (item[this._itemSourceAttribute] && (!this._itemValidator || this._itemValidator(item))) {\n let file = { source : item[this._itemSourceAttribute] , target : '' };\n\n if (item[this._itemTargetAttribute]) {\n file.target = item[this._itemTargetAttribute];\n } else {\n file.target = Util.getNameHash(file.source);\n }\n\n output.push(file);\n }\n }\n\n return output;\n }\n\n start() {\n this.on('complete', (event:any) => {\n if ((event.index + 1) >= event.length) {\n this.replicationFinalized(event.index);\n }\n });\n\n this.on('error', (event:any) => {\n this.replicationFinalized(event.index);\n }); \n\n this.downloadFiles(this._files, this._fileHandler);\n }\n\n replicationFinalized(lastIndex:number) { \n if (lastIndex+1 >= this._files.length) { // all finished\n this._files = [];\n this.emit('final');\n } else if (this._retryTimeout > 0) { // restart after last success \n this._files.splice(0,lastIndex);\n setTimeout(() => { \n this.downloadFiles(this._files, this._fileHandler);\n }, this._retryTimeout);\n } \n }\n\n}"
,
"export const CONFIG_ITEM_KEY = \"itemKey\";\nexport const CONFIG_ITEM_VALUE = \"itemValue\";\nexport const CONFIG_ITEM_SOURCE_ATTRIBUTE = \"itemSourceAttribute\";\nexport const CONFIG_ITEM_TARGET_ATTRIBUTE = \"itemTargetAttribute\";\nexport const CONFIG_ITEM_VALIDATOR = \"itemValidator\";\nexport const CONFIG_RETRY_TIMEOUT = \"retryTimeout\";\nexport const CONFIG_FILE_HANDLER = \"fileHandler\";\n\nexport class Config {\n\n protected config:any = {};\n\n hasConfig(key:string) {\n if (this.config[key]) {\n return true;\n }\n return false;\n }\n\n getConfig(key:string) {\n return this.config[key];\n }\n\n setConfig(key:string, value:any) {\n this.config[key] = value;\n }\n\n}"
,
"import {FileHandler} from './api/file-handler';\nimport {ElectronFileHandler} from './file-handler/electron-file-handler';\nimport {CordovaDownloader} from './file-handler/cordova-file-handler';\nimport {FileReplicator} from './file-replicator';\nimport {\n Config,\n CONFIG_RETRY_TIMEOUT,\n CONFIG_ITEM_KEY,\n CONFIG_ITEM_VALUE,\n CONFIG_ITEM_TARGET_ATTRIBUTE,\n CONFIG_ITEM_SOURCE_ATTRIBUTE\n} from './config';\n\nexport const ENV_ELECTRON = \"electron\";\nexport const ENV_CORDOVA = \"cordova\";\nexport const ENV_UNKNOWN = \"unknown\";\n\nexport class ServiceLocator {\n\n protected static fileHandlers:any = {};\n protected static fileReplicator: FileReplicator;\n protected static config: Config;\n\n static addFileHandler(environment:string, fileHandler:FileHandler) {\n ServiceLocator.fileHandlers[environment] = fileHandler;\n }\n\n static getConfig() : Config {\n if (!ServiceLocator.config) {\n ServiceLocator.config = new Config();\n }\n\n return ServiceLocator.config;\n }\n\n static getEnvironment() {\n if (typeof window['require'] === 'function' && window['require']('electron')) {\n return ENV_ELECTRON;\n }\n if (typeof window['FileTransfer'] === 'function') {\n return ENV_CORDOVA;\n }\n\n return ENV_UNKNOWN;\n }\n\n static getFileHandler() : FileHandler {\n let environment = ServiceLocator.getEnvironment();\n\n if (ServiceLocator.fileHandlers[environment]) {\n return ServiceLocator.fileHandlers[environment];\n }\n\n if (environment === ENV_ELECTRON) {\n return new ElectronFileHandler(window['require']('electron').ipcRenderer);\n }\n\n if (environment === ENV_CORDOVA) {\n return new CordovaDownloader();\n }\n \n return null;\n }\n\n static getFileReplicator() : FileReplicator {\n if (!ServiceLocator.fileReplicator) {\n\n ServiceLocator.fileReplicator = new FileReplicator();\n\n ServiceLocator.fileReplicator.fileHandler = ServiceLocator.getFileHandler();\n\n if (ServiceLocator.getConfig().hasConfig(CONFIG_RETRY_TIMEOUT)) {\n ServiceLocator.fileReplicator.retryTimeout = ServiceLocator.getConfig().getConfig(CONFIG_RETRY_TIMEOUT);\n }\n if (ServiceLocator.getConfig().hasConfig(CONFIG_ITEM_KEY)) {\n ServiceLocator.fileReplicator.itemKey = ServiceLocator.getConfig().getConfig(CONFIG_ITEM_KEY);\n }\n if (ServiceLocator.getConfig().hasConfig(CONFIG_ITEM_VALUE)) {\n ServiceLocator.fileReplicator.itemValue = ServiceLocator.getConfig().getConfig(CONFIG_ITEM_VALUE);\n }\n if (ServiceLocator.getConfig().hasConfig(CONFIG_ITEM_SOURCE_ATTRIBUTE)) {\n ServiceLocator.fileReplicator.itemSourceAttribute = ServiceLocator.getConfig().getConfig(CONFIG_ITEM_SOURCE_ATTRIBUTE);\n }\n if (ServiceLocator.getConfig().hasConfig(CONFIG_ITEM_TARGET_ATTRIBUTE)) {\n ServiceLocator.fileReplicator.itemTargetAttribute = ServiceLocator.getConfig().getConfig(CONFIG_ITEM_TARGET_ATTRIBUTE);\n }\n } \n\n return ServiceLocator.fileReplicator;\n }\n\n}"
,
"import { EventEmitter } from 'events';\nimport { ServiceLocator } from './service-locator';\n\nexport * from './service-locator';\n\nexport function loadBsyncPlugin (PouchDB) {\n let pouchReplicate = PouchDB.replicate; \n\n PouchDB.plugin((PouchDB) => {\n PouchDB.replicate = function() {\n let eventEmitter = new EventEmitter();\n let emitter = pouchReplicate.apply(this, arguments);\n let replicator = ServiceLocator.getFileReplicator();\n let db = arguments[1]; \n \n replicator.once('final', event => { \n eventEmitter.emit('complete');\n eventEmitter.removeAllListeners();\n });\n\n replicator.on('error', event => {\n eventEmitter.emit('file-replicator-error', event);\n });\n\n replicator.on('complete', event => {\n eventEmitter.emit('file-replicator-complete', event);\n });\n\n replicator.on('progress', event => {\n eventEmitter.emit('file-replicator-progress', event);\n });\n \n emitter.once('change', info => { \n eventEmitter.emit('change', info);\n });\n\n emitter.once('complete', info => { \n db.query('index_type/type',{\n include_docs : true,\n key : replicator.itemValue\n }).then((res) => { \n let docs = { docs : [] }; \n for (let r of res.rows) {\n docs.docs.push(r.doc);\n }\n\n replicator.pushChanges(docs);\n replicator.start();\n }).catch(error => {\n eventEmitter.emit('error', error);\n });\n });\n\n emitter.once('error', (error) => {\n eventEmitter.emit('error', error);\n });\n\n return eventEmitter;\n };\n });\n};\n\nif (typeof window !== 'undefined' && window['PouchDB']) {\n loadBsyncPlugin(window['PouchDB']);\n}\n"
],
"names"
:[
"Observable"
,
"EventEmitter"
],
"mappings"
:
"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"
}
\ No newline at end of file
{
"version"
:
3
,
"file"
:
null
,
"sources"
:[
"../node_modules/rollup-plugin-node-builtins/src/es6/events.js"
,
"../src/file-handler/electron-file-handler.ts"
,
"../src/util.ts"
,
"../src/file-handler/cordova-file-handler.ts"
,
"../src/file-replicator.ts"
,
"../src/config.ts"
,
"../src/service-locator.ts"
],
"sourcesContent"
:[
"'use strict';\n\nvar domain;\n\n// This constructor is used to store event handlers. Instantiating this is\n// faster than explicitly calling `Object.create(null)` to get a \"clean\" empty\n// object (tested with v8 v4.9).\nfunction EventHandlers() {}\nEventHandlers.prototype = Object.create(null);\n\nfunction EventEmitter() {\n EventEmitter.init.call(this);\n}\nexport default EventEmitter;\nexport {EventEmitter};\n\nEventEmitter.usingDomains = false;\n\nEventEmitter.prototype.domain = undefined;\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\nEventEmitter.init = function() {\n this.domain = null;\n if (EventEmitter.usingDomains) {\n // if there is an active domain, then attach to it.\n if (domain.active && !(this instanceof domain.Domain)) {\n this.domain = domain.active;\n }\n }\n\n if (!this._events || this._events === Object.getPrototypeOf(this)._events) {\n this._events = new EventHandlers();\n this._eventsCount = 0;\n }\n\n this._maxListeners = this._maxListeners || undefined;\n};\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {\n if (typeof n !== 'number' || n < 0 || isNaN(n))\n throw new TypeError('\"n\" argument must be a positive number');\n this._maxListeners = n;\n return this;\n};\n\nfunction $getMaxListeners(that) {\n if (that._maxListeners === undefined)\n return EventEmitter.defaultMaxListeners;\n return that._maxListeners;\n}\n\nEventEmitter.prototype.getMaxListeners = function getMaxListeners() {\n return $getMaxListeners(this);\n};\n\n// These standalone emit* functions are used to optimize calling of event\n// handlers for fast cases because emit() itself often has a variable number of\n// arguments and can be deoptimized because of that. These functions always have\n// the same number of arguments and thus do not get deoptimized, so the code\n// inside them can execute faster.\nfunction emitNone(handler, isFn, self) {\n if (isFn)\n handler.call(self);\n else {\n var len = handler.length;\n var listeners = arrayClone(handler, len);\n for (var i = 0; i < len; ++i)\n listeners[i].call(self);\n }\n}\nfunction emitOne(handler, isFn, self, arg1) {\n if (isFn)\n handler.call(self, arg1);\n else {\n var len = handler.length;\n var listeners = arrayClone(handler, len);\n for (var i = 0; i < len; ++i)\n listeners[i].call(self, arg1);\n }\n}\nfunction emitTwo(handler, isFn, self, arg1, arg2) {\n if (isFn)\n handler.call(self, arg1, arg2);\n else {\n var len = handler.length;\n var listeners = arrayClone(handler, len);\n for (var i = 0; i < len; ++i)\n listeners[i].call(self, arg1, arg2);\n }\n}\nfunction emitThree(handler, isFn, self, arg1, arg2, arg3) {\n if (isFn)\n handler.call(self, arg1, arg2, arg3);\n else {\n var len = handler.length;\n var listeners = arrayClone(handler, len);\n for (var i = 0; i < len; ++i)\n listeners[i].call(self, arg1, arg2, arg3);\n }\n}\n\nfunction emitMany(handler, isFn, self, args) {\n if (isFn)\n handler.apply(self, args);\n else {\n var len = handler.length;\n var listeners = arrayClone(handler, len);\n for (var i = 0; i < len; ++i)\n listeners[i].apply(self, args);\n }\n}\n\nEventEmitter.prototype.emit = function emit(type) {\n var er, handler, len, args, i, events, domain;\n var needDomainExit = false;\n var doError = (type === 'error');\n\n events = this._events;\n if (events)\n doError = (doError && events.error == null);\n else if (!doError)\n return false;\n\n domain = this.domain;\n\n // If there is no 'error' event listener then throw.\n if (doError) {\n er = arguments[1];\n if (domain) {\n if (!er)\n er = new Error('Uncaught, unspecified \"error\" event');\n er.domainEmitter = this;\n er.domain = domain;\n er.domainThrown = false;\n domain.emit('error', er);\n } else if (er instanceof Error) {\n throw er; // Unhandled 'error' event\n } else {\n // At least give some kind of context to the user\n var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n err.context = er;\n throw err;\n }\n return false;\n }\n\n handler = events[type];\n\n if (!handler)\n return false;\n\n var isFn = typeof handler === 'function';\n len = arguments.length;\n switch (len) {\n // fast cases\n case 1:\n emitNone(handler, isFn, this);\n break;\n case 2:\n emitOne(handler, isFn, this, arguments[1]);\n break;\n case 3:\n emitTwo(handler, isFn, this, arguments[1], arguments[2]);\n break;\n case 4:\n emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]);\n break;\n // slower\n default:\n args = new Array(len - 1);\n for (i = 1; i < len; i++)\n args[i - 1] = arguments[i];\n emitMany(handler, isFn, this, args);\n }\n\n if (needDomainExit)\n domain.exit();\n\n return true;\n};\n\nfunction _addListener(target, type, listener, prepend) {\n var m;\n var events;\n var existing;\n\n if (typeof listener !== 'function')\n throw new TypeError('\"listener\" argument must be a function');\n\n events = target._events;\n if (!events) {\n events = target._events = new EventHandlers();\n target._eventsCount = 0;\n } else {\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (events.newListener) {\n target.emit('newListener', type,\n listener.listener ? listener.listener : listener);\n\n // Re-assign `events` because a newListener handler could have caused the\n // this._events to be assigned to a new object\n events = target._events;\n }\n existing = events[type];\n }\n\n if (!existing) {\n // Optimize the case of one listener. Don't need the extra array object.\n existing = events[type] = listener;\n ++target._eventsCount;\n } else {\n if (typeof existing === 'function') {\n // Adding the second element, need to change to array.\n existing = events[type] = prepend ? [listener, existing] :\n [existing, listener];\n } else {\n // If we've already got an array, just append.\n if (prepend) {\n existing.unshift(listener);\n } else {\n existing.push(listener);\n }\n }\n\n // Check for listener leak\n if (!existing.warned) {\n m = $getMaxListeners(target);\n if (m && m > 0 && existing.length > m) {\n existing.warned = true;\n var w = new Error('Possible EventEmitter memory leak detected. ' +\n existing.length + ' ' + type + ' listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit');\n w.name = 'MaxListenersExceededWarning';\n w.emitter = target;\n w.type = type;\n w.count = existing.length;\n emitWarning(w);\n }\n }\n }\n\n return target;\n}\nfunction emitWarning(e) {\n typeof console.warn === 'function' ? console.warn(e) : console.log(e);\n}\nEventEmitter.prototype.addListener = function addListener(type, listener) {\n return _addListener(this, type, listener, false);\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.prependListener =\n function prependListener(type, listener) {\n return _addListener(this, type, listener, true);\n };\n\nfunction _onceWrap(target, type, listener) {\n var fired = false;\n function g() {\n target.removeListener(type, g);\n if (!fired) {\n fired = true;\n listener.apply(target, arguments);\n }\n }\n g.listener = listener;\n return g;\n}\n\nEventEmitter.prototype.once = function once(type, listener) {\n if (typeof listener !== 'function')\n throw new TypeError('\"listener\" argument must be a function');\n this.on(type, _onceWrap(this, type, listener));\n return this;\n};\n\nEventEmitter.prototype.prependOnceListener =\n function prependOnceListener(type, listener) {\n if (typeof listener !== 'function')\n throw new TypeError('\"listener\" argument must be a function');\n this.prependListener(type, _onceWrap(this, type, listener));\n return this;\n };\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener =\n function removeListener(type, listener) {\n var list, events, position, i, originalListener;\n\n if (typeof listener !== 'function')\n throw new TypeError('\"listener\" argument must be a function');\n\n events = this._events;\n if (!events)\n return this;\n\n list = events[type];\n if (!list)\n return this;\n\n if (list === listener || (list.listener && list.listener === listener)) {\n if (--this._eventsCount === 0)\n this._events = new EventHandlers();\n else {\n delete events[type];\n if (events.removeListener)\n this.emit('removeListener', type, list.listener || listener);\n }\n } else if (typeof list !== 'function') {\n position = -1;\n\n for (i = list.length; i-- > 0;) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener)) {\n originalListener = list[i].listener;\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (list.length === 1) {\n list[0] = undefined;\n if (--this._eventsCount === 0) {\n this._events = new EventHandlers();\n return this;\n } else {\n delete events[type];\n }\n } else {\n spliceOne(list, position);\n }\n\n if (events.removeListener)\n this.emit('removeListener', type, originalListener || listener);\n }\n\n return this;\n };\n\nEventEmitter.prototype.removeAllListeners =\n function removeAllListeners(type) {\n var listeners, events;\n\n events = this._events;\n if (!events)\n return this;\n\n // not listening for removeListener, no need to emit\n if (!events.removeListener) {\n if (arguments.length === 0) {\n this._events = new EventHandlers();\n this._eventsCount = 0;\n } else if (events[type]) {\n if (--this._eventsCount === 0)\n this._events = new EventHandlers();\n else\n delete events[type];\n }\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n var keys = Object.keys(events);\n for (var i = 0, key; i < keys.length; ++i) {\n key = keys[i];\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = new EventHandlers();\n this._eventsCount = 0;\n return this;\n }\n\n listeners = events[type];\n\n if (typeof listeners === 'function') {\n this.removeListener(type, listeners);\n } else if (listeners) {\n // LIFO order\n do {\n this.removeListener(type, listeners[listeners.length - 1]);\n } while (listeners[0]);\n }\n\n return this;\n };\n\nEventEmitter.prototype.listeners = function listeners(type) {\n var evlistener;\n var ret;\n var events = this._events;\n\n if (!events)\n ret = [];\n else {\n evlistener = events[type];\n if (!evlistener)\n ret = [];\n else if (typeof evlistener === 'function')\n ret = [evlistener.listener || evlistener];\n else\n ret = unwrapListeners(evlistener);\n }\n\n return ret;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n if (typeof emitter.listenerCount === 'function') {\n return emitter.listenerCount(type);\n } else {\n return listenerCount.call(emitter, type);\n }\n};\n\nEventEmitter.prototype.listenerCount = listenerCount;\nfunction listenerCount(type) {\n var events = this._events;\n\n if (events) {\n var evlistener = events[type];\n\n if (typeof evlistener === 'function') {\n return 1;\n } else if (evlistener) {\n return evlistener.length;\n }\n }\n\n return 0;\n}\n\nEventEmitter.prototype.eventNames = function eventNames() {\n return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : [];\n};\n\n// About 1.5x faster than the two-arg version of Array#splice().\nfunction spliceOne(list, index) {\n for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1)\n list[i] = list[k];\n list.pop();\n}\n\nfunction arrayClone(arr, i) {\n var copy = new Array(i);\n while (i--)\n copy[i] = arr[i];\n return copy;\n}\n\nfunction unwrapListeners(arr) {\n var ret = new Array(arr.length);\n for (var i = 0; i < ret.length; ++i) {\n ret[i] = arr[i].listener || arr[i];\n }\n return ret;\n}\n"
,
"import { EventEmitter } from 'events';\nimport { FileHandler } from '../api/file-handler';\nimport { File } from '../api/file';\n\nexport class ElectronFileHandler extends EventEmitter implements FileHandler {\n\n constructor (private ipcRenderer:any) {\n super();\n }\n\n download(source:string, target:string) {\n this.ipcRenderer.once('bsync-download-complete', () => {\n this.ipcRenderer.removeAllListeners('bsync-download-progress');\n this.ipcRenderer.removeAllListeners('bsync-download-error');\n this.emit('complete');\n });\n\n this.ipcRenderer.on('bsync-download-progress', (progress:number) => {\n this.emit('progress', progress);\n });\n\n this.ipcRenderer.once('bsync-download-error', (error:any) => {\n this.ipcRenderer.removeAllListeners('bsync-download-progress');\n this.ipcRenderer.removeAllListeners('bsync-download-complete');\n this.emit('error', error);\n });\n\n this.ipcRenderer.send('bsync-download', {\n source : source ,\n target : target\n });\n\n return this; \n }\n\n cleanup(files:Array<File>) : Promise<void> {\n return new Promise<void>((resolve, reject) => {\n\n this.ipcRenderer.once('bsync-cleanup-complete', () => {\n this.emit('cleanup-complete');\n resolve();\n });\n\n this.ipcRenderer.send('bsync-cleanup', files);\n\n });\n }\n\n}"
,
"import { File } from './api/file';\n\nexport class Util {\n\n static getNameHash(path:string) {\n for(var r=0,i=0;i<path.length;i++) {\n r=(r<<5)-r+path.charCodeAt(i),r&=r;\n }\n return \"bsync_\" + Math.abs(r);\n }\n\n /**\n * index >= 0, localFile is in files\n * index < 0, localFile is not in files\n */\n static getFileIndex(files:Array<File>, localFile:string) : number {\n for (let i = 0; i < files.length; i++) {\n if (localFile == files[i].target) {\n return i;\n }\n }\n return -1;\n }\n\n static getFilesForCleanup(files:Array<File>, localFiles:Array<string>) : Array<string> {\n let filesForCleanup = [];\n\n for (let localFile of localFiles) {\n let index = -1;\n\n index = Util.getFileIndex(files, localFile);\n \n if (index < 0) {\n filesForCleanup.push(localFile);\n } else {\n // splice for performance improvement only\n files.splice(index,1);\n }\n }\n\n return filesForCleanup;\n }\n\n}"
,
"import { Util } from './../util';\nimport { EventEmitter } from 'events';\nimport { FileHandler } from '../api/file-handler';\nimport { File } from '../api/file';\n\nexport class CordovaFileHandler extends EventEmitter implements FileHandler {\n\n triggerFileTransfer(source:string, target:string) {\n let fileTransfer = new window['FileTransfer']();\n\n fileTransfer.onprogress = (progress:ProgressEvent) => {\n this.emit('progress', progress.loaded / progress.total);\n };\n\n fileTransfer.download(\n source ,\n target ,\n (entry:any) => {\n this.emit('complete', entry);\n } ,\n (error:any) => {\n this.emit('error', error);\n },\n true\n );\n }\n\n download(source:string, target:string) {\n if (!window['FileTransfer']) {\n this.emit('error','Cordova FileTransfer object undefined');\n }\n\n window['resolveLocalFileSystemURL'](target, (entry:any) => {\n entry.getMetadata((metadata) => {\n if (metadata.size > 0) {\n this.emit('complete', entry);\n } else {\n // file empty trigger transfer\n this.triggerFileTransfer(source,target);\n }\n }, () => {\n // cannot read metadata trigger transfer\n this.triggerFileTransfer(source,target);\n });\n }, () => {\n // file not found, so download it\n this.triggerFileTransfer(source,target);\n });\n\n return this; \n }\n\n cleanup(files:Array<File>, basePath:string) : Promise<void> {\n let filesForCleanup = [];\n\n return new Promise<void>((resolve, reject) => {\n\n if (window['resolveLocalFileSystemURL']) {\n window['resolveLocalFileSystemURL'](basePath, (entry) => {\n let reader = entry.createReader();\n reader.readEntries((entries) => {\n\n for (let e of entries) {\n if (e && e.isFile) {\n if (Util.getFileIndex(files, e.name) < 0) {\n filesForCleanup.push(e);\n }\n }\n }\n \n let index = 0;\n let error = false;\n\n let cleanupError = (error) => {\n this.emit('cleanup-error', error);\n reject();\n error = true;\n };\n\n let cleanupNext = () => {\n if (index < filesForCleanup.length && !error) {\n filesForCleanup[index].remove(cleanupNext, cleanupError);\n index += 1;\n } else if (!error) { \n this.emit('cleanup-complete', filesForCleanup);\n resolve();\n }\n };\n \n cleanupNext();\n\n }, (error) => { this.emit('cleanup-error', error); reject(); });\n });\n }\n\n });\n }\n\n}"
,
"import { FileHandler } from './api/file-handler';\nimport { File } from './api/file';\nimport { Util } from './util';\nimport { EventEmitter } from 'events';\n\nexport class FileReplicator extends EventEmitter {\n\n constructor() {\n super();\n }\n\n protected _files: Array<File> = [];\n\n protected _itemValidator: (item: any) => boolean = null;\n protected _fileHandler: FileHandler = null;\n protected _retryTimeout: number = 100;\n protected _retries: number = 10;\n\n protected _itemKey = \"type\";\n protected _itemValue = \"asset\";\n protected _itemSourceAttribute = \"source\";\n protected _itemTargetAttribute = \"target\";\n protected _targetDirectory = \"\";\n\n get files(): Array<File> {\n return this._files;\n }\n\n set fileHandler(handler: FileHandler) {\n this._fileHandler = handler;\n }\n\n get fileHandler() : FileHandler {\n return this._fileHandler;\n }\n\n set retryTimeout(timeout: number) {\n this._retryTimeout = timeout;\n }\n\n set itemValidator(validator: (item: any) => boolean) {\n this._itemValidator = validator;\n }\n\n set itemKey(key: string) {\n this._itemKey = key;\n }\n\n set itemValue(value: string) {\n this._itemValue = value;\n }\n\n set itemSourceAttribute(sourceAttribute: string) {\n this._itemSourceAttribute = sourceAttribute;\n }\n\n set itemTargetAttribute(targetAttribute: string) {\n this._itemTargetAttribute = targetAttribute;\n }\n\n get itemKey() {\n return this._itemKey;\n }\n\n get itemValue() {\n return this._itemValue;\n }\n\n get itemSourceAttribute() {\n return this._itemSourceAttribute;\n }\n\n get itemTargetAttribute() {\n return this._itemTargetAttribute;\n }\n\n set targetDirectory(targetDirectory: string) {\n this._targetDirectory = targetDirectory;\n }\n\n get targetDirectory() {\n return this._targetDirectory;\n }\n\n clear(files: Array<File> = []) {\n this._files = files;\n }\n\n /**\n * change from pouchdb replicate\n */\n pushChanges(docs: Array<any>) {\n let items: Array<any> = [];\n\n if (docs && docs.length > 0) {\n for (let item of docs) {\n if (item[this._itemKey] && item[this._itemKey] === this._itemValue) {\n items.push(item);\n }\n }\n }\n\n let files = this.prepareFiles(items);\n\n for (let file of files) {\n this._files.push(file);\n }\n }\n\n downloadFiles(files: Array<File>, fileHandler: FileHandler, index: number = 0) {\n if (index >= files.length) {\n return;\n }\n\n this.emit('start', { progress: 0, index: index, length: files.length });\n \n fileHandler\n .on('progress', (progress) => {\n this.emit('file-progress', { progress: progress, index: index, length: files.length })\n })\n .once('error', error => {\n this.emit('file-error', { progress: 0, index: index, length: files.length, error: error });\n fileHandler.removeAllListeners();\n })\n .once('complete', () => {\n this.emit('file-complete', { progress: 100, index: index, length: files.length });\n fileHandler.removeAllListeners();\n this.downloadFiles(files, fileHandler, index + 1);\n })\n .download(files[index].source, this.targetDirectory + files[index].target); \n }\n\n prepareFiles(items: Array<any>): Array<File> {\n let output = [];\n\n for (let item of items) {\n if (item[this._itemSourceAttribute] && (!this._itemValidator || this._itemValidator(item))) {\n let file = { source: item[this._itemSourceAttribute], target: '' };\n\n if (item[this._itemTargetAttribute]) {\n file.target = item[this._itemTargetAttribute];\n } else {\n file.target = Util.getNameHash(file.source);\n }\n\n output.push(file);\n }\n }\n\n return output;\n }\n\n start(retries:number = 10) {\n this._retries = retries;\n\n this.on('file-complete', (event: any) => {\n if ((event.index + 1) >= event.length) {\n this.replicationFinalized(event.index);\n }\n });\n\n this.on('file-error', (event: any) => {\n this.replicationFinalized(event.index);\n });\n\n if (this._fileHandler && this._files.length > 0) {\n this.downloadFiles(this._files, this._fileHandler);\n } else {\n this.emit('complete');\n } \n }\n\n cleanup() {\n this.fileHandler\n .cleanup(this._files, this._targetDirectory)\n .then(() => {\n this.emit('cleanup-complete');\n }).catch(() => {\n this.emit('cleanup-error');\n });\n }\n\n replicationFinalized(lastIndex: number) {\n if (lastIndex + 1 >= this._files.length) { // all finished\n this.emit('complete');\n } else if (this._retries > 0) { // restart after last success \n this._files.splice(0, lastIndex);\n setTimeout(() => {\n this._retries =- 1;\n this.downloadFiles(this._files, this._fileHandler);\n }, this._retryTimeout);\n } else {\n this.emit('error');\n }\n }\n\n}"
,
"export const CONFIG_ITEM_KEY = \"itemKey\";\nexport const CONFIG_ITEM_VALUE = \"itemValue\";\nexport const CONFIG_ITEM_SOURCE_ATTRIBUTE = \"itemSourceAttribute\";\nexport const CONFIG_ITEM_TARGET_ATTRIBUTE = \"itemTargetAttribute\";\nexport const CONFIG_ITEM_VALIDATOR = \"itemValidator\";\nexport const CONFIG_RETRY_TIMEOUT = \"retryTimeout\";\nexport const CONFIG_FILE_HANDLER = \"fileHandler\";\nexport const CONFIG_TARGET_DIRECTORY = \"targetDirectory\";\n\nexport class Config {\n\n protected config:any = {};\n\n hasConfig(key:string) : boolean {\n if (this.config[key]) {\n return true;\n }\n return false;\n }\n\n getConfig(key:string) : any {\n return this.config[key];\n }\n\n setConfig(key:string, value:any) : Config {\n this.config[key] = value;\n return this;\n }\n\n}"
,
"import {FileHandler} from './api/file-handler';\nimport {ElectronFileHandler} from './file-handler/electron-file-handler';\nimport {CordovaFileHandler} from './file-handler/cordova-file-handler';\nimport {FileReplicator} from './file-replicator';\nimport {\n Config,\n CONFIG_RETRY_TIMEOUT,\n CONFIG_ITEM_KEY,\n CONFIG_ITEM_VALUE,\n CONFIG_ITEM_TARGET_ATTRIBUTE,\n CONFIG_ITEM_SOURCE_ATTRIBUTE,\n CONFIG_TARGET_DIRECTORY\n} from './config';\n\nexport const ENV_ELECTRON = \"electron\";\nexport const ENV_CORDOVA = \"cordova\";\nexport const ENV_UNKNOWN = \"unknown\";\n\nexport class ServiceLocator {\n\n protected static fileHandlers:any = {};\n protected static fileReplicator: FileReplicator;\n protected static config: Config;\n\n static addFileHandler(environment:string, fileHandler:FileHandler) {\n ServiceLocator.fileHandlers[environment] = fileHandler;\n }\n\n static getConfig() : Config {\n if (!ServiceLocator.config) {\n ServiceLocator.config = new Config();\n }\n\n return ServiceLocator.config;\n }\n\n static getEnvironment() {\n if (typeof window['require'] === 'function' && window['require']('electron')) {\n return ENV_ELECTRON;\n }\n if (typeof window['FileTransfer'] === 'function') {\n return ENV_CORDOVA;\n }\n\n return ENV_UNKNOWN;\n }\n\n static getFileHandler() : FileHandler {\n let environment = ServiceLocator.getEnvironment();\n\n if (ServiceLocator.fileHandlers[environment]) {\n return ServiceLocator.fileHandlers[environment];\n }\n\n if (environment === ENV_ELECTRON) {\n return new ElectronFileHandler(window['require']('electron').ipcRenderer);\n }\n\n if (environment === ENV_CORDOVA) {\n return new CordovaFileHandler();\n }\n \n return null;\n }\n\n static getFileReplicator() : FileReplicator {\n if (!ServiceLocator.fileReplicator) {\n ServiceLocator.fileReplicator = new FileReplicator();\n ServiceLocator.fileReplicator.fileHandler = ServiceLocator.getFileHandler();\n }\n\n if (ServiceLocator.getConfig().hasConfig(CONFIG_RETRY_TIMEOUT)) {\n ServiceLocator.fileReplicator.retryTimeout = ServiceLocator.getConfig().getConfig(CONFIG_RETRY_TIMEOUT);\n }\n if (ServiceLocator.getConfig().hasConfig(CONFIG_ITEM_KEY)) {\n ServiceLocator.fileReplicator.itemKey = ServiceLocator.getConfig().getConfig(CONFIG_ITEM_KEY);\n }\n if (ServiceLocator.getConfig().hasConfig(CONFIG_ITEM_VALUE)) {\n ServiceLocator.fileReplicator.itemValue = ServiceLocator.getConfig().getConfig(CONFIG_ITEM_VALUE);\n }\n if (ServiceLocator.getConfig().hasConfig(CONFIG_ITEM_SOURCE_ATTRIBUTE)) {\n ServiceLocator.fileReplicator.itemSourceAttribute = ServiceLocator.getConfig().getConfig(CONFIG_ITEM_SOURCE_ATTRIBUTE);\n }\n if (ServiceLocator.getConfig().hasConfig(CONFIG_ITEM_TARGET_ATTRIBUTE)) {\n ServiceLocator.fileReplicator.itemTargetAttribute = ServiceLocator.getConfig().getConfig(CONFIG_ITEM_TARGET_ATTRIBUTE);\n }\n if (ServiceLocator.getConfig().hasConfig(CONFIG_TARGET_DIRECTORY)) {\n ServiceLocator.fileReplicator.targetDirectory = ServiceLocator.getConfig().getConfig(CONFIG_TARGET_DIRECTORY);\n }\n \n return ServiceLocator.fileReplicator;\n }\n\n}"
],
"names"
:[],
"mappings"
:
"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"
}
\ No newline at end of file
...
...
dist/node-build.js
View file @
6fb2e37
'use strict'
;
var
rxjs_Observable
=
require
(
'rxjs/Observable
'
);
var
events
=
require
(
'events
'
);
var
http
=
require
(
'http'
);
var
https
=
require
(
'https'
);
var
fs
=
require
(
'fs'
);
var
NodeFileHandler
=
(
function
()
{
function
__extends
(
d
,
b
)
{
for
(
var
p
in
b
)
if
(
b
.
hasOwnProperty
(
p
))
d
[
p
]
=
b
[
p
];
function
__
()
{
this
.
constructor
=
d
;
}
d
.
prototype
=
b
===
null
?
Object
.
create
(
b
)
:
(
__
.
prototype
=
b
.
prototype
,
new
__
());
}
var
Util
=
(
function
()
{
function
Util
()
{
}
Util
.
getNameHash
=
function
(
path
)
{
for
(
var
r
=
0
,
i
=
0
;
i
<
path
.
length
;
i
++
)
{
r
=
(
r
<<
5
)
-
r
+
path
.
charCodeAt
(
i
),
r
&=
r
;
}
return
"bsync_"
+
Math
.
abs
(
r
);
};
/**
* index >= 0, localFile is in files
* index < 0, localFile is not in files
*/
Util
.
getFileIndex
=
function
(
files
,
localFile
)
{
for
(
var
i
=
0
;
i
<
files
.
length
;
i
++
)
{
if
(
localFile
==
files
[
i
].
target
)
{
return
i
;
}
}
return
-
1
;
};
Util
.
getFilesForCleanup
=
function
(
files
,
localFiles
)
{
var
filesForCleanup
=
[];
for
(
var
_i
=
0
,
localFiles_1
=
localFiles
;
_i
<
localFiles_1
.
length
;
_i
++
)
{
var
localFile
=
localFiles_1
[
_i
];
var
index
=
-
1
;
index
=
Util
.
getFileIndex
(
files
,
localFile
);
if
(
index
<
0
)
{
filesForCleanup
.
push
(
localFile
);
}
else
{
// splice for performance improvement only
files
.
splice
(
index
,
1
);
}
}
return
filesForCleanup
;
};
return
Util
;
}());
var
NodeFileHandler
=
(
function
(
_super
)
{
__extends
(
NodeFileHandler
,
_super
);
function
NodeFileHandler
()
{
_super
.
apply
(
this
,
arguments
);
}
NodeFileHandler
.
prototype
.
selectProtocol
=
function
(
url
)
{
if
(
url
.
search
(
/^http:
\/\/
/
)
===
0
)
{
...
...
@@ -20,18 +68,19 @@ var NodeFileHandler = (function () {
}
};
NodeFileHandler
.
prototype
.
download
=
function
(
source
,
target
)
{
var
_this
=
this
;
var
handler
=
this
.
selectProtocol
(
source
);
return
rxjs_Observable
.
Observable
.
create
(
function
(
subscriber
)
{
if
(
!
handler
)
{
subscriber
.
error
(
"No handler for source: "
+
source
);
return
;
this
.
emit
(
"error"
,
"No handler for source: "
+
source
);
return
this
;
}
// file already exists and is not empty
if
(
fs
.
existsSync
(
target
)
&&
(
fs
.
statSync
(
target
)[
'size'
]
>
0
))
{
subscriber
.
complete
(
);
return
;
this
.
emit
(
"complete"
);
return
this
;
}
var
file
=
fs
.
createWriteStream
(
target
,
{
'flags'
:
'a'
});
else
{
var
file_1
=
fs
.
createWriteStream
(
target
,
{
'flags'
:
'a'
});
handler
.
get
(
source
,
function
(
response
)
{
var
size
=
response
.
headers
[
'content-length'
];
// in bytes
var
prog
=
0
;
// already downloaded
...
...
@@ -39,33 +88,53 @@ var NodeFileHandler = (function () {
var
nextProg
=
(
1
/
progCounts
);
response
.
on
(
'data'
,
function
(
chunk
)
{
prog
+=
chunk
.
length
;
file
.
write
(
chunk
,
'binary'
);
file
_1
.
write
(
chunk
,
'binary'
);
if
((
prog
/
size
)
>
nextProg
)
{
subscriber
.
next
(
prog
/
size
);
_this
.
emit
(
'progress'
,
prog
/
size
);
nextProg
+=
(
1
/
progCounts
);
}
});
response
.
on
(
'end'
,
function
()
{
file
.
end
();
subscriber
.
complete
(
);
response
.
on
ce
(
'end'
,
function
()
{
file
_1
.
end
();
_this
.
emit
(
'complete'
);
});
}).
on
(
'error'
,
function
(
error
)
{
fs
.
unlink
(
target
);
subscriber
.
error
(
"Error while downloading: "
+
error
);
_this
.
emit
(
"error"
,
"Error while downloading: "
+
error
);
});
return
this
;
}
};
NodeFileHandler
.
prototype
.
cleanup
=
function
(
files
,
basePath
)
{
try
{
var
localFiles
=
fs
.
readdirSync
(
basePath
);
Util
.
getFilesForCleanup
(
files
,
localFiles
)
.
forEach
(
function
(
file
)
{
fs
.
unlinkSync
(
basePath
+
"/"
+
file
);
});
}
catch
(
e
)
{
}
return
this
;
};
return
NodeFileHandler
;
}());
}(
events
.
EventEmitter
));
var
Bsync
=
(
function
()
{
function
Bsync
()
{
}
Bsync
.
configIpcMain
=
function
(
ipcMain
,
downloadDir
)
{
var
nodeFileHander
=
new
NodeFileHandler
();
Bsync
.
configIpcMain
=
function
(
ipcMain
,
basePath
)
{
ipcMain
.
on
(
'bsync-download'
,
function
(
event
,
args
)
{
nodeFileHander
.
download
(
args
.
source
,
downloadDir
+
args
.
target
)
.
subscribe
(
function
(
progress
)
{
event
.
sender
.
send
(
'bsync-download-progress'
,
progress
);
},
function
(
error
)
{
event
.
sender
.
send
(
'bsync-download-error'
,
error
);
},
function
()
{
event
.
sender
.
send
(
'bsync-download-complete'
);
});
var
nodeFileHander
=
new
NodeFileHandler
();
nodeFileHander
.
download
(
args
.
source
,
basePath
+
"/"
+
args
.
target
)
.
on
(
'progress'
,
function
(
progress
)
{
event
.
sender
.
send
(
'bsync-download-progress'
,
progress
);
})
.
once
(
'error'
,
function
(
error
)
{
nodeFileHander
.
removeAllListeners
();
event
.
sender
.
send
(
'bsync-download-error'
,
error
);
})
.
once
(
'complete'
,
function
()
{
nodeFileHander
.
removeAllListeners
();
event
.
sender
.
send
(
'bsync-download-complete'
);
});
});
ipcMain
.
on
(
'bsync-cleanup'
,
function
(
event
,
args
)
{
var
nodeFileHandler
=
new
NodeFileHandler
();
nodeFileHandler
.
cleanup
(
args
.
files
,
basePath
);
event
.
sender
.
send
(
'bsync-cleanup-complete'
);
});
};
return
Bsync
;
...
...
dist/node-build.js.map
View file @
6fb2e37
{
"version"
:
3
,
"file"
:
null
,
"sources"
:[
"../src/file-handler/node-file-handler.ts"
,
"../src/node-main.ts"
],
"sourcesContent"
:[
"import { Observable } from 'rxjs/Observable';\nimport { Subscriber } from 'rxjs/Subscriber';\nimport { FileHandler } from '../api/file-handler';\nimport * as http from 'http';\nimport * as https from 'https';\nimport * as fs from 'fs';\n\nexport class NodeFileHandler implements FileHandler {\n\n selectProtocol(url:string) : any {\n if (url.search(/^http:\\/\\//) === 0) {\n return http;\n } else if (url.search(/^https:\\/\\//) === 0) {\n return https;\n } else {\n return null;\n }\n }\n\n download(source:string, target:string) : Observable<number> {\n\n let handler = this.selectProtocol(source);\n\n return Observable.create((subscriber:Subscriber<number>) => {\n \n if (!handler) {\n subscriber.error(\"No handler for source: \" + source);\n return;\n }\n\n // file already exists and is not empty\n if (fs.existsSync(target) && (fs.statSync(target)['size'] > 0)) {\n subscriber.complete();\n return;\n }\n\n let file = fs.createWriteStream(target, {'flags': 'a'});\n\n handler.get(source, (response) => {\n let size = response.headers['content-length']; // in bytes\n let prog = 0; // already downloaded\n let progCounts = 100; // how many progress events should be triggerd (1-100 %)\n let nextProg = (1/progCounts);\n \n response.on('data', (chunk) => {\n prog += chunk.length;\n file.write(chunk, 'binary');\n\n if ((prog / size) > nextProg) {\n subscriber.next(prog / size);\n nextProg += (1 / progCounts);\n } \n });\n\n response.on('end', () => {\n file.end();\n subscriber.complete();\n });\n \n }).on('error', (error) => {\n fs.unlink(target);\n subscriber.error(\"Error while downloading: \" + error);\n });\n\n });\n\n }\n\n}"
,
"import { NodeFileHandler } from './file-handler/node-file-handler';\n\nexport default class Bsync {\n\n static configIpcMain(ipcMain: any, downloadDir:string) {\n let nodeFileHander = new NodeFileHandler();\n\n ipcMain.on('bsync-download', (event, args) => {\n nodeFileHander.download(args.source, downloadDir + args.target)\n .subscribe(\n (progress:number) => { event.sender.send('bsync-download-progress', progress); } ,\n (error:any) => { event.sender.send('bsync-download-error', error); } ,\n () => { event.sender.send('bsync-download-complete'); }\n );\n });\n }\n\n}"
],
"names"
:[
"Observable"
,
"fs.existsSync"
,
"fs.statSync"
,
"fs.createWriteStream"
,
"fs.unlink"
],
"mappings"
:
"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"
}
\ No newline at end of file
{
"version"
:
3
,
"file"
:
null
,
"sources"
:[
"../src/util.ts"
,
"../src/file-handler/node-file-handler.ts"
,
"../src/node-main.ts"
],
"sourcesContent"
:[
"import { File } from './api/file';\n\nexport class Util {\n\n static getNameHash(path:string) {\n for(var r=0,i=0;i<path.length;i++) {\n r=(r<<5)-r+path.charCodeAt(i),r&=r;\n }\n return \"bsync_\" + Math.abs(r);\n }\n\n /**\n * index >= 0, localFile is in files\n * index < 0, localFile is not in files\n */\n static getFileIndex(files:Array<File>, localFile:string) : number {\n for (let i = 0; i < files.length; i++) {\n if (localFile == files[i].target) {\n return i;\n }\n }\n return -1;\n }\n\n static getFilesForCleanup(files:Array<File>, localFiles:Array<string>) : Array<string> {\n let filesForCleanup = [];\n\n for (let localFile of localFiles) {\n let index = -1;\n\n index = Util.getFileIndex(files, localFile);\n \n if (index < 0) {\n filesForCleanup.push(localFile);\n } else {\n // splice for performance improvement only\n files.splice(index,1);\n }\n }\n\n return filesForCleanup;\n }\n\n}"
,
"import { Util } from './../util';\nimport { EventEmitter } from 'events';\nimport { FileHandler } from '../api/file-handler';\nimport { File } from '../api/file';\nimport * as http from 'http';\nimport * as https from 'https';\nimport * as fs from 'fs';\n\nexport class NodeFileHandler extends EventEmitter implements FileHandler {\n\n selectProtocol(url:string) : any {\n if (url.search(/^http:\\/\\//) === 0) {\n return http;\n } else if (url.search(/^https:\\/\\//) === 0) {\n return https;\n } else {\n return null;\n }\n }\n\n download(source:string, target:string) {\n\n let handler = this.selectProtocol(source);\n\n if (!handler) {\n this.emit(\"error\",\"No handler for source: \" + source);\n return this;\n }\n\n // file already exists and is not empty\n if (fs.existsSync(target) && (fs.statSync(target)['size'] > 0)) {\n this.emit(\"complete\");\n return this;\n } else {\n let file = fs.createWriteStream(target, {'flags': 'a'});\n\n handler.get(source, (response) => {\n let size = response.headers['content-length']; // in bytes\n let prog = 0; // already downloaded\n let progCounts = 100; // how many progress events should be triggerd (1-100 %)\n let nextProg = (1/progCounts);\n \n response.on('data', (chunk) => {\n prog += chunk.length;\n file.write(chunk, 'binary');\n\n if ((prog / size) > nextProg) {\n this.emit('progress',prog / size);\n nextProg += (1 / progCounts);\n } \n });\n\n response.once('end', () => {\n file.end();\n this.emit('complete');\n }); \n\n }).on('error', (error) => {\n fs.unlink(target);\n this.emit(\"error\", \"Error while downloading: \" + error);\n });\n\n return this;\n } \n }\n\n cleanup(files:Array<File>, basePath?:string) {\n try {\n let localFiles = fs.readdirSync(basePath);\n Util.getFilesForCleanup(files, localFiles)\n .forEach((file) => {\n fs.unlinkSync(basePath + \"/\" + file);\n }); \n } catch (e) {\n }\n \n return this;\n }\n\n}"
,
"import { NodeFileHandler } from './file-handler/node-file-handler';\n\nexport default class Bsync {\n\n static configIpcMain(ipcMain: any, basePath: string) { \n \n ipcMain.on('bsync-download', (event, args) => {\n let nodeFileHander = new NodeFileHandler();\n nodeFileHander.download(args.source, basePath + \"/\" + args.target)\n .on('progress', (progress:number) => { event.sender.send('bsync-download-progress', progress); })\n .once('error', (error) => { nodeFileHander.removeAllListeners(); event.sender.send('bsync-download-error', error); })\n .once('complete', () => { nodeFileHander.removeAllListeners(); event.sender.send('bsync-download-complete'); });\n });\n\n ipcMain.on('bsync-cleanup', (event, args) => {\n let nodeFileHandler = new NodeFileHandler();\n nodeFileHandler.cleanup(args.files, basePath);\n event.sender.send('bsync-cleanup-complete');\n });\n\n }\n\n}"
],
"names"
:[
"fs.existsSync"
,
"fs.statSync"
,
"fs.createWriteStream"
,
"fs.unlink"
,
"fs.readdirSync"
,
"fs.unlinkSync"
,
"EventEmitter"
],
"mappings"
:
"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"
}
\ No newline at end of file
...
...
index.d.ts
0 → 100644
View file @
6fb2e37
interface
FileReplicator
{
start
(
retries
?:
number
)
:
void
;
clear
()
:
void
;
cleanup
()
:
void
;
pushChanges
(
change
:
any
)
:
void
;
on
(
event
:
string
,
handler
:(...
params
:
any
[])
=>
void
)
:
FileReplicator
;
once
(
event
:
string
,
handler
:(...
params
:
any
[])
=>
void
)
:
FileReplicator
;
removeAllListeners
()
:
FileReplicator
;
}
declare
var
bsyncClient
:
{
CONFIG_TARGET_DIRECTORY
:
string
;
ServiceLocator
:
{
getConfig
:
()
=>
{
getConfig
:
(
key
:
string
)
=>
any
;
setConfig
:
(
key
:
string
,
value
:
any
)
=>
void
;
hasConfig
:
(
key
:
string
)
=>
boolean
;
};
getFileReplicator
:
()
=>
FileReplicator
;
}
};
declare
module
"bsync-client"
{
export
=
bsyncClient
;
}
\ No newline at end of file
package.json
View file @
6fb2e37
...
...
@@ -3,6 +3,7 @@
"version"
:
"1.0.0"
,
"description"
:
""
,
"main"
:
"dist/browser-build.js"
,
"typings"
:
"index.d.ts"
,
"scripts"
:
{
"build"
:
"npm run build:node && npm run build:browser"
,
"build:node"
:
"rollup -c ./config/rollup.config.node.js"
,
...
...
@@ -16,9 +17,6 @@
},
"author"
:
""
,
"license"
:
"ISC"
,
"dependencies"
:
{
"rxjs"
:
"^5.0.2"
},
"devDependencies"
:
{
"@types/jasmine"
:
"^2.5.40"
,
"cordova"
:
"^6.4.0"
,
...
...
scripts/after-test.sh
View file @
6fb2e37
#!/bin/bash
curl -X DELETE http://admin:admin@127.0.0.1:5984/pouch_test_db
rm -R ./.tmp
\ No newline at end of file
rm -rf ./.tmp
rm -rf ./.tmp-files
\ No newline at end of file
...
...
scripts/before-test.sh
View file @
6fb2e37
#!/bin/bash
rm -rf ./.tmp
rm -rf ./.tmp-files
curl -X DELETE http://admin:admin@127.0.0.1:5984/pouch_test_db
curl -X PUT http://admin:admin@127.0.0.1:5984/pouch_test_db
...
...
scripts/prepare-cordova-test.sh
View file @
6fb2e37
...
...
@@ -7,15 +7,14 @@ echo "cordova $COMMAND $PLATFORM"
rollup --config ./config/rollup.config.cordova-test.js
cp ./spec/cordova-plugin-test/plugin.xml .tmp/plugin.xml
cp ./node_modules/rxjs/bundles/Rx.min.js .tmp/Rx.min.js
cd
..
rm -r ./bsync-client-test-app
rm -r
f
./bsync-client-test-app
./bsync-client/node_modules/.bin/cordova create bsync-client-test-app
cd
./bsync-client-test-app
../bsync-client/node_modules/.bin/cordova platform add
$PLATFORM
../bsync-client/node_modules/.bin/cordova plugin add ../bsync-client
#
../bsync-client/node_modules/.bin/cordova plugin add ../bsync-client
../bsync-client/node_modules/.bin/cordova plugin add ../bsync-client/.tmp
../bsync-client/node_modules/.bin/cordova plugin add cordova-plugin-test-framework
...
...
@@ -27,4 +26,4 @@ else
cordova emulate
$PLATFORM
fi
rm -R ../bsync-client/.tmp
\ No newline at end of file
rm -rf ../bsync-client/.tmp
\ No newline at end of file
...
...
spec/browser-test.ts
View file @
6fb2e37
...
...
@@ -5,8 +5,6 @@ import {TestFileHandler} from './file-handler/test-file-handler';
ServiceLocator
.
addFileHandler
(
ENV_UNKNOWN
,
new
TestFileHandler
());
import
'../src/browser-main'
;
declare
var
emit
:
any
;
const
dbUrl
=
'http://admin:admin@localhost:5984/pouch_test_db'
;
...
...
@@ -49,32 +47,71 @@ describe("Integration tests with couchdb", () => {
it
(
"Should successfully download several files"
,
(
done
)
=>
{
TestFileHandler
.
setErrorRate
(
0
);
ServiceLocator
.
getFileReplicator
().
init
();
let
replicator
=
ServiceLocator
.
getFileReplicator
();
let
index
=
0
;
localDb
.
replicate
.
from
(
dbUrl
)
.
on
(
'file-replicator-complete'
,
event
=>
{
replicator
.
clear
();
replicator
.
on
(
'file-complete'
,
()
=>
{
index
++
;
})
.
on
(
'complete'
,
()
=>
{
.
on
ce
(
'complete'
,
()
=>
{
expect
(
index
).
toEqual
(
3
);
done
();
});
localDb
.
replicate
.
from
(
dbUrl
)
.
once
(
'complete'
,
()
=>
{
localDb
.
query
(
'index_type/type'
,{
include_docs
:
true
,
key
:
replicator
.
itemValue
}).
then
((
res
)
=>
{
let
docs
=
[];
for
(
let
r
of
res
.
rows
)
{
docs
.
push
(
r
.
doc
);
}
replicator
.
pushChanges
(
docs
);
replicator
.
start
();
});
});
});
it
(
"Should trigger errors, but successfully download with retries"
,
(
done
)
=>
{
TestFileHandler
.
setErrorRate
(
0.8
);
ServiceLocator
.
getFileReplicator
().
init
();
let
replicator
=
ServiceLocator
.
getFileReplicator
();
let
errors
=
0
;
localDb
.
replicate
.
from
(
dbUrl
)
.
on
(
'file-replicator-error'
,
event
=>
{
replicator
.
clear
();
replicator
.
on
(
'file-error'
,
()
=>
{
errors
++
;
})
.
on
(
'complete'
,
()
=>
{
.
on
ce
(
'complete'
,
()
=>
{
expect
(
errors
).
toBeGreaterThanOrEqual
(
1
);
done
();
});
localDb
.
replicate
.
from
(
dbUrl
)
.
once
(
'complete'
,
()
=>
{
localDb
.
query
(
'index_type/type'
,{
include_docs
:
true
,
key
:
replicator
.
itemValue
}).
then
((
res
)
=>
{
let
docs
=
[];
for
(
let
r
of
res
.
rows
)
{
docs
.
push
(
r
.
doc
);
}
replicator
.
pushChanges
(
docs
);
replicator
.
start
();
});
});
});
});
...
...
spec/cordova-plugin-test/plugin.xml
View file @
6fb2e37
...
...
@@ -5,14 +5,11 @@
version=
"1.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
>
<name>
bsync
cordova tes
t
</name>
<name>
bsync
test in cordova environmen
t
</name>
<license>
Apache 2.0 License
</license>
<js-module
src=
"Rx.min.js"
name=
"Rx"
>
<clobbers
target=
"Rx"
/>
</js-module>
<js-module
src=
"cordova-test-build.js"
name=
"tests"
>
</js-module>
<dependency
id=
"cordova-plugin-file-transfer"
url=
"https://github.com/apache/cordova-plugin-file-transfer"
commit=
"master"
/>
</plugin>
\ No newline at end of file
...
...
spec/cordova-test.ts
View file @
6fb2e37
import
{
Cordova
Download
er
}
from
'../src/file-handler/cordova-file-handler'
;
import
{
Cordova
FileHandl
er
}
from
'../src/file-handler/cordova-file-handler'
;
declare
var
cordova
;
exports
.
defineAutoTests
=
function
()
{
let
createFilesHelper
=
(
filenames
:
Array
<
string
>
,
successCallback
,
errorCallback
)
=>
{
let
index
=
0
;
let
create
=
()
=>
{
if
(
index
<
filenames
.
length
)
{
console
.
log
(
"try creating file: "
,
filenames
[
index
]);
createFileHelper
(
filenames
[
index
],
create
,
errorCallback
);
index
+=
1
;
}
else
{
successCallback
();
}
};
create
();
};
let
createFileHelper
=
(
filename
,
successCallback
,
errorCallback
)
=>
{
window
[
'requestFileSystem'
](
window
[
'LocalFileSystem'
].
TEMPORARY
,
0
,
(
fs
)
=>
{
fs
.
root
.
getFile
(
filename
,
{
create
:
true
,
exclusive
:
false
},(
fileEntry
)
=>
{
fileEntry
.
createWriter
((
fileWriter
)
=>
{
fileWriter
.
onwriteend
=
function
()
{
console
.
log
(
"file created"
,
filename
);
successCallback
();
};
fileWriter
.
onerror
=
function
(
e
)
{
console
.
error
(
"file error"
,
e
);
errorCallback
(
e
);
};
fileWriter
.
write
(
new
Blob
([
'some arbitrary file data'
],
{
type
:
'text/plain'
}));
});
},
errorCallback
);
},
errorCallback
);
};
jasmine
.
DEFAULT_TIMEOUT_INTERVAL
=
100000
;
describe
(
"Cordova downloader"
,
()
=>
{
let
downloader
=
new
CordovaDownload
er
();
let
handler
=
new
CordovaFileHandl
er
();
it
(
"should download sample image from https source and store with new name"
,
(
done
)
=>
{
let
source
=
"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e1/FullMoon2010.jpg/800px-FullMoon2010.jpg"
;
let
target
=
cordova
.
file
.
dataDirectory
+
"full-moon.jpg"
;
let
source
=
"https://upload.wikimedia.org/wikipedia/commons/f/ff/Pizigani_1367_Chart_10MB.jpg"
;
// let target = cordova.file.dataDirectory + "full-moon.jpg";
let
target
=
"cdvfile://localhost/temporary/full-moon.jpg"
;
let
lastProgress
=
0
;
downloader
.
download
(
source
,
target
)
.
subscribe
(
(
progress
:
number
)
=>
{
handler
.
download
(
source
,
target
)
.
on
(
'progress'
,
(
progress
:
number
)
=>
{
expect
(
progress
).
toBeGreaterThan
(
lastProgress
);
lastProgress
=
progress
;
}
,
(
error
:
any
)
=>
{
}).
once
(
'error'
,
(
error
:
any
)
=>
{
fail
();
}
,
()
=>
{
}).
once
(
'complete'
,
()
=>
{
expect
(
lastProgress
).
toEqual
(
1
);
window
[
'resolveLocalFileSystemURL'
](
target
,
(
entry
:
any
)
=>
{
...
...
@@ -31,9 +64,31 @@ exports.defineAutoTests = function() {
expect
(
entry
.
name
).
toEqual
(
"full-moon.jpg"
);
done
();
});
}
);
});
});
it
(
'should cleanup successfully'
,
(
done
)
=>
{
createFilesHelper
([
'file-1'
,
'file-2'
,
'file-3'
],
()
=>
{
console
.
log
(
"files are created, now start with cleanup"
);
handler
.
once
(
'cleanup-complete'
,
(
files
)
=>
{
console
.
log
(
files
);
expect
(
files
.
length
).
toBeGreaterThan
(
1
);
done
();
});
handler
.
once
(
'cleanup-error'
,
(
files
)
=>
{
fail
(
'cleanup error'
);
});
handler
.
cleanup
([
{
source
:
''
,
target
:
'file-1'
}
,
{
source
:
''
,
target
:
'file-2'
}
],
'cdvfile://localhost/temporary/'
);
},
(
error
)
=>
{
console
.
error
(
error
);
fail
(
'error while creating files'
);
});
});
});
...
...
spec/file-handler/test-file-handler.ts
View file @
6fb2e37
import
{
Observable
,
Subscriber
}
from
'rxj
s'
;
import
{
EventEmitter
}
from
'event
s'
;
import
{
FileHandler
}
from
'../../src/api/file-handler'
;
export
class
TestFileHandler
implements
FileHandler
{
export
class
TestFileHandler
extends
EventEmitter
implements
FileHandler
{
protected
static
errorRate
:
number
=
0
;
...
...
@@ -9,27 +9,30 @@ export class TestFileHandler implements FileHandler {
TestFileHandler
.
errorRate
=
rate
;
}
download
(
source
:
string
,
target
:
string
)
:
Observable
<
number
>
{
return
Observable
.
create
((
subscriber
:
Subscriber
<
number
>
)
=>
{
cleanup
()
{
return
this
;
}
download
(
source
:
string
,
target
:
string
)
{
let
random
=
Math
.
random
();
let
error
:
boolean
=
random
<
TestFileHandler
.
errorRate
;
let
counter
=
1
;
if
(
error
)
{
subscriber
.
error
(
"random error triggered"
);
return
;
}
setTimeout
(()
=>
{
this
.
emit
(
"error"
,
"random error triggered"
)
;
}
,
200
);
}
else
{
let
interval
=
setInterval
(()
=>
{
if
(
counter
<
4
)
{
subscriber
.
next
(
counter
*
25
);
this
.
emit
(
'progress'
,
counter
*
25
);
}
else
{
subscriber
.
complete
(
);
this
.
emit
(
'complete'
);
clearInterval
(
interval
);
}
++
counter
;
},
10
);
});
}
return
this
;
}
}
\ No newline at end of file
...
...
spec/node-test.ts
View file @
6fb2e37
export
*
from
'./test/file-handler/node-file-handler'
;
export
*
from
'./test/file-replicator'
;
export
*
from
'./test/util'
;
\ No newline at end of file
...
...
spec/test/file-handler/node-file-handler.ts
View file @
6fb2e37
...
...
@@ -7,6 +7,10 @@ describe("Node Downloader", () => {
let
nodeFileHandler
=
new
NodeFileHandler
();
beforeEach
(()
=>
{
nodeFileHandler
.
removeAllListeners
();
});
it
(
"should retrieve right handler"
,
()
=>
{
let
httpHandler
=
nodeFileHandler
.
selectProtocol
(
"http://someurl.com/image.jpg"
);
...
...
@@ -23,27 +27,26 @@ describe("Node Downloader", () => {
it
(
"should download sample image from https source and store with new name"
,
(
done
)
=>
{
let
source
=
"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e1/FullMoon2010.jpg/800px-FullMoon2010.jpg"
;
let
target
=
".
tmp/full-moon
.jpg"
;
let
target
=
".
/.tmp/full-moon-"
+
(
new
Date
()).
getTime
()
+
"
.jpg"
;
let
lastProgress
=
0
;
nodeFileHandler
.
download
(
source
,
target
)
.
subscribe
(
(
progress
:
number
)
=>
{
nodeFileHandler
.
on
(
'progress'
,
(
progress
:
number
)
=>
{
expect
(
progress
).
toBeGreaterThan
(
lastProgress
);
lastProgress
=
progress
;
}
,
(
error
:
any
)
=>
{}
,
()
=>
{
})
.
once
(
'error'
,
(
error
)
=>
{})
.
once
(
'complete'
,
()
=>
{
expect
(
lastProgress
).
toEqual
(
1
);
expect
(
fs
.
existsSync
(
target
)).
toBeTruthy
();
done
();
}
);
})
.
download
(
source
,
target
);
});
it
(
'should not download if file with same name exists and bytesize > 0'
,
(
done
)
=>
{
let
source
=
"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e1/FullMoon2010.jpg/800px-FullMoon2010.jpg"
;
let
target
=
".tmp/full-moon-sensless.jpg"
;
let
target
=
".
/.
tmp/full-moon-sensless.jpg"
;
let
lastProgress
=
0
;
let
file
=
fs
.
createWriteStream
(
target
,
{
'flags'
:
'a'
});
...
...
@@ -51,18 +54,32 @@ describe("Node Downloader", () => {
file
.
write
(
new
Buffer
(
dummyData
));
file
.
end
(()
=>
{
nodeFileHandler
.
download
(
source
,
target
)
.
subscribe
(
()
=>
{
fail
(
"progress should not be called"
);
}
,
()
=>
{}
,
()
=>
{
nodeFileHandler
.
on
(
'progress'
,
()
=>
{
fail
(
"progress should not be called"
);
})
.
once
(
'error'
,
()
=>
{})
.
once
(
'complete'
,
()
=>
{
expect
(
fs
.
existsSync
(
target
)).
toBeTruthy
();
done
();
}
);
}
)
.
download
(
source
,
target
);
});
});
it
(
'should correctly cleanup files'
,
()
=>
{
let
basePath
=
"./.tmp-files"
;
fs
.
mkdirSync
(
basePath
);
fs
.
writeFileSync
(
basePath
+
"/file1"
,
"some data for file 1"
);
fs
.
writeFileSync
(
basePath
+
"/file2"
,
"some data for file 2"
);
fs
.
writeFileSync
(
basePath
+
"/file3"
,
"some data for file 3"
);
fs
.
writeFileSync
(
basePath
+
"/file4"
,
"some data for file 4"
);
nodeFileHandler
.
cleanup
([
{
source
:
''
,
target
:
'file1'
},
{
source
:
''
,
target
:
'file2'
}],
basePath
);
let
files
=
fs
.
readdirSync
(
basePath
);
expect
(
files
.
length
).
toEqual
(
2
);
});
});
\ No newline at end of file
...
...
spec/test/file-replicator.ts
View file @
6fb2e37
import
{
FileReplicator
}
from
'../../src/file-replicator'
;
describe
(
"File Replicator"
,
()
=>
{
let
fileReplicator
=
new
FileReplicator
();
let
change
=
{
docs
:
[
let
change
=
[
{
language
:
'de'
,
type
:
"asset"
,
source
:
"http://someplace.com/icon.jpg"
,
target
:
"icon.jpg"
}
,
{
language
:
'de'
,
type
:
"asset"
,
source
:
"http://sampleuri.com/image.png"
}
,
{
language
:
'en'
,
type
:
"asset"
,
source
:
"https://secureasset.com/asset.mp3"
,
target
:
"music.mp3"
}
]
};
];
beforeEach
(()
=>
{
fileReplicator
.
init
();
fileReplicator
.
clear
();
});
it
(
"should contain several assets"
,
()
=>
{
...
...
@@ -23,7 +20,7 @@ describe("File Replicator", () => {
});
it
(
"should get correct asset names"
,
()
=>
{
let
files
=
fileReplicator
.
prepareFiles
(
change
.
docs
);
let
files
=
fileReplicator
.
prepareFiles
(
change
);
expect
(
files
[
0
].
target
).
toEqual
(
"icon.jpg"
);
expect
(
files
[
1
].
target
).
toEqual
(
"bsync_707608502"
);
...
...
@@ -38,7 +35,7 @@ describe("File Replicator", () => {
return
false
;
};
let
files
=
fileReplicator
.
prepareFiles
(
change
.
docs
);
let
files
=
fileReplicator
.
prepareFiles
(
change
);
expect
(
files
.
length
).
toEqual
(
2
);
expect
(
files
[
0
].
target
).
toEqual
(
"icon.jpg"
);
...
...
spec/test/util.ts
0 → 100644
View file @
6fb2e37
import
{
Util
}
from
'../../src/util'
;
describe
(
'Util'
,
()
=>
{
let
files
=
[
{
source
:
''
,
target
:
'file-1'
}
,
{
source
:
''
,
target
:
'file-2'
}
,
{
source
:
''
,
target
:
'file-3'
}
,
];
it
(
'should show files to remove'
,
()
=>
{
let
cleanupFiles
=
Util
.
getFilesForCleanup
(
files
,
[
'file-1'
,
'file-4'
]);
expect
(
cleanupFiles
[
0
]).
toEqual
(
'file-4'
);
});
});
\ No newline at end of file
src/api/file-handler.ts
View file @
6fb2e37
import
{
Observable
}
from
'rxjs/Observab
le'
;
import
{
File
}
from
'./fi
le'
;
export
interface
FileHandler
{
...
...
@@ -8,6 +8,17 @@ export interface FileHandler {
* - if the download is in progress: trigger next (0-1 progress for percent of download)
* - if the download enters any error condition, trigger error and an already downloaded part of the file
*/
download
(
source
:
string
,
target
:
string
)
:
Observable
<
number
>
;
download
(
source
:
string
,
target
:
string
)
:
FileHandler
;
/**
* Remove all files, which are not inside the files array from local storage
*/
cleanup
(
files
:
Array
<
File
>
,
basePath
?:
string
);
on
(
event
:
string
,
handler
:(...
params
:
any
[])
=>
void
)
:
FileHandler
;
once
(
event
:
string
,
handler
:(...
params
:
any
[])
=>
void
)
:
FileHandler
;
removeAllListeners
()
:
FileHandler
;
}
\ No newline at end of file
...
...
src/browser-main.ts
View file @
6fb2e37
import
{
EventEmitter
}
from
'events'
;
import
{
ServiceLocator
}
from
'./service-locator'
;
export
*
from
'./service-locator'
;
export
function
loadBsyncPlugin
(
PouchDB
)
{
let
pouchReplicate
=
PouchDB
.
replicate
;
PouchDB
.
plugin
((
PouchDB
)
=>
{
PouchDB
.
replicate
=
function
()
{
let
eventEmitter
=
new
EventEmitter
();
let
emitter
=
pouchReplicate
.
apply
(
this
,
arguments
);
let
replicator
=
ServiceLocator
.
getFileReplicator
();
let
db
=
arguments
[
1
];
replicator
.
once
(
'final'
,
event
=>
{
eventEmitter
.
emit
(
'complete'
);
eventEmitter
.
removeAllListeners
();
});
replicator
.
on
(
'error'
,
event
=>
{
eventEmitter
.
emit
(
'file-replicator-error'
,
event
);
});
replicator
.
on
(
'complete'
,
event
=>
{
eventEmitter
.
emit
(
'file-replicator-complete'
,
event
);
});
replicator
.
on
(
'progress'
,
event
=>
{
eventEmitter
.
emit
(
'file-replicator-progress'
,
event
);
});
emitter
.
once
(
'change'
,
info
=>
{
eventEmitter
.
emit
(
'change'
,
info
);
});
emitter
.
once
(
'complete'
,
info
=>
{
db
.
query
(
'index_type/type'
,{
include_docs
:
true
,
key
:
replicator
.
itemValue
}).
then
((
res
)
=>
{
let
docs
=
{
docs
:
[]
};
for
(
let
r
of
res
.
rows
)
{
docs
.
docs
.
push
(
r
.
doc
);
}
replicator
.
pushChanges
(
docs
);
replicator
.
start
();
}).
catch
(
error
=>
{
eventEmitter
.
emit
(
'error'
,
error
);
});
});
emitter
.
once
(
'error'
,
(
error
)
=>
{
eventEmitter
.
emit
(
'error'
,
error
);
});
return
eventEmitter
;
};
});
};
if
(
typeof
window
!==
'undefined'
&&
window
[
'PouchDB'
])
{
loadBsyncPlugin
(
window
[
'PouchDB'
]);
}
export
*
from
'./config'
;
...
...
src/config.ts
View file @
6fb2e37
...
...
@@ -5,24 +5,26 @@ export const CONFIG_ITEM_TARGET_ATTRIBUTE = "itemTargetAttribute";
export
const
CONFIG_ITEM_VALIDATOR
=
"itemValidator"
;
export
const
CONFIG_RETRY_TIMEOUT
=
"retryTimeout"
;
export
const
CONFIG_FILE_HANDLER
=
"fileHandler"
;
export
const
CONFIG_TARGET_DIRECTORY
=
"targetDirectory"
;
export
class
Config
{
protected
config
:
any
=
{};
hasConfig
(
key
:
string
)
{
hasConfig
(
key
:
string
)
:
boolean
{
if
(
this
.
config
[
key
])
{
return
true
;
}
return
false
;
}
getConfig
(
key
:
string
)
{
getConfig
(
key
:
string
)
:
any
{
return
this
.
config
[
key
];
}
setConfig
(
key
:
string
,
value
:
any
)
{
setConfig
(
key
:
string
,
value
:
any
)
:
Config
{
this
.
config
[
key
]
=
value
;
return
this
;
}
}
\ No newline at end of file
...
...
src/file-handler/cordova-file-handler.ts
View file @
6fb2e37
import
{
Util
}
from
'./../util'
;
import
{
EventEmitter
}
from
'events'
;
import
{
FileHandler
}
from
'../api/file-handler'
;
import
{
File
}
from
'../api/file'
;
declare
var
Rx
;
export
class
CordovaDownloader
implements
FileHandler
{
download
(
source
:
string
,
target
:
string
)
:
Rx
.
Observable
<
number
>
{
return
Rx
.
Observable
.
create
((
subscriber
:
Rx
.
Subscriber
<
number
>
)
=>
{
if
(
!
window
[
'FileTransfer'
])
{
subscriber
.
error
(
"Cordova FileTransfer object undefined"
);
}
export
class
CordovaFileHandler
extends
EventEmitter
implements
FileHandler
{
triggerFileTransfer
(
source
:
string
,
target
:
string
)
{
let
fileTransfer
=
new
window
[
'FileTransfer'
]();
fileTransfer
.
onprogress
=
(
progress
:
ProgressEvent
)
=>
{
subscriber
.
next
(
progress
.
loaded
/
progress
.
total
);
this
.
emit
(
'progress'
,
progress
.
loaded
/
progress
.
total
);
};
fileTransfer
.
download
(
source
,
target
,
(
entry
:
any
)
=>
{
subscriber
.
complete
(
);
this
.
emit
(
'complete'
,
entry
);
}
,
(
error
:
any
)
=>
{
subscriber
.
error
(
error
);
this
.
emit
(
'error'
,
error
);
},
true
);
}
download
(
source
:
string
,
target
:
string
)
{
if
(
!
window
[
'FileTransfer'
])
{
this
.
emit
(
'error'
,
'Cordova FileTransfer object undefined'
);
}
window
[
'resolveLocalFileSystemURL'
](
target
,
(
entry
:
any
)
=>
{
entry
.
getMetadata
((
metadata
)
=>
{
if
(
metadata
.
size
>
0
)
{
this
.
emit
(
'complete'
,
entry
);
}
else
{
// file empty trigger transfer
this
.
triggerFileTransfer
(
source
,
target
);
}
},
()
=>
{
// cannot read metadata trigger transfer
this
.
triggerFileTransfer
(
source
,
target
);
});
},
()
=>
{
// file not found, so download it
this
.
triggerFileTransfer
(
source
,
target
);
});
return
this
;
}
cleanup
(
files
:
Array
<
File
>
,
basePath
:
string
)
:
Promise
<
void
>
{
let
filesForCleanup
=
[];
return
new
Promise
<
void
>
((
resolve
,
reject
)
=>
{
if
(
window
[
'resolveLocalFileSystemURL'
])
{
window
[
'resolveLocalFileSystemURL'
](
basePath
,
(
entry
)
=>
{
let
reader
=
entry
.
createReader
();
reader
.
readEntries
((
entries
)
=>
{
for
(
let
e
of
entries
)
{
if
(
e
&&
e
.
isFile
)
{
if
(
Util
.
getFileIndex
(
files
,
e
.
name
)
<
0
)
{
filesForCleanup
.
push
(
e
);
}
}
}
let
index
=
0
;
let
error
=
false
;
let
cleanupError
=
(
error
)
=>
{
this
.
emit
(
'cleanup-error'
,
error
);
reject
();
error
=
true
;
};
let
cleanupNext
=
()
=>
{
if
(
index
<
filesForCleanup
.
length
&&
!
error
)
{
filesForCleanup
[
index
].
remove
(
cleanupNext
,
cleanupError
);
index
+=
1
;
}
else
if
(
!
error
)
{
this
.
emit
(
'cleanup-complete'
,
filesForCleanup
);
resolve
();
}
};
cleanupNext
();
},
(
error
)
=>
{
this
.
emit
(
'cleanup-error'
,
error
);
reject
();
});
});
}
});
}
...
...
src/file-handler/electron-file-handler.ts
View file @
6fb2e37
import
{
Observable
,
Subscriber
}
from
'rxj
s'
;
import
{
EventEmitter
}
from
'event
s'
;
import
{
FileHandler
}
from
'../api/file-handler'
;
import
{
File
}
from
'../api/file'
;
export
class
ElectronFileHandler
implements
FileHandler
{
export
class
ElectronFileHandler
extends
EventEmitter
implements
FileHandler
{
constructor
(
private
ipcRenderer
:
any
)
{
super
();
}
download
(
source
:
string
,
target
:
string
)
:
Observable
<
number
>
{
return
Observable
.
create
((
subscriber
:
Subscriber
<
number
>
)
=>
{
download
(
source
:
string
,
target
:
string
)
{
this
.
ipcRenderer
.
once
(
'bsync-download-complete'
,
()
=>
{
this
.
ipcRenderer
.
removeAllListeners
(
'bsync-download-progress'
);
this
.
ipcRenderer
.
removeAllListeners
(
'bsync-download-error'
);
subscriber
.
complete
(
);
this
.
emit
(
'complete'
);
});
this
.
ipcRenderer
.
on
(
'bsync-download-progress'
,
(
progress
:
number
)
=>
{
subscriber
.
next
(
progress
);
this
.
emit
(
'progress'
,
progress
);
});
this
.
ipcRenderer
.
once
(
'bsync-download-error'
,
(
error
:
any
)
=>
{
this
.
ipcRenderer
.
removeAllListeners
(
'bsync-download-progress'
);
this
.
ipcRenderer
.
removeAllListeners
(
'bsync-download-complete'
);
subscriber
.
error
(
error
);
this
.
emit
(
'error'
,
error
);
});
this
.
ipcRenderer
.
send
(
'bsync-download'
,
{
source
:
source
,
target
:
target
});
return
this
;
}
cleanup
(
files
:
Array
<
File
>
)
:
Promise
<
void
>
{
return
new
Promise
<
void
>
((
resolve
,
reject
)
=>
{
this
.
ipcRenderer
.
once
(
'bsync-cleanup-complete'
,
()
=>
{
this
.
emit
(
'cleanup-complete'
);
resolve
();
});
this
.
ipcRenderer
.
send
(
'bsync-cleanup'
,
files
);
});
}
...
...
src/file-handler/node-file-handler.ts
View file @
6fb2e37
import
{
Observable
}
from
'rxjs/Observable
'
;
import
{
Subscriber
}
from
'rxjs/Subscriber
'
;
import
{
Util
}
from
'./../util
'
;
import
{
EventEmitter
}
from
'events
'
;
import
{
FileHandler
}
from
'../api/file-handler'
;
import
{
File
}
from
'../api/file'
;
import
*
as
http
from
'http'
;
import
*
as
https
from
'https'
;
import
*
as
fs
from
'fs'
;
export
class
NodeFileHandler
implements
FileHandler
{
export
class
NodeFileHandler
extends
EventEmitter
implements
FileHandler
{
selectProtocol
(
url
:
string
)
:
any
{
if
(
url
.
search
(
/^http:
\/\/
/
)
===
0
)
{
...
...
@@ -17,23 +18,20 @@ export class NodeFileHandler implements FileHandler {
}
}
download
(
source
:
string
,
target
:
string
)
:
Observable
<
number
>
{
download
(
source
:
string
,
target
:
string
)
{
let
handler
=
this
.
selectProtocol
(
source
);
return
Observable
.
create
((
subscriber
:
Subscriber
<
number
>
)
=>
{
if
(
!
handler
)
{
subscriber
.
error
(
"No handler for source: "
+
source
);
return
;
this
.
emit
(
"error"
,
"No handler for source: "
+
source
);
return
this
;
}
// file already exists and is not empty
if
(
fs
.
existsSync
(
target
)
&&
(
fs
.
statSync
(
target
)[
'size'
]
>
0
))
{
subscriber
.
complete
();
return
;
}
this
.
emit
(
"complete"
);
return
this
;
}
else
{
let
file
=
fs
.
createWriteStream
(
target
,
{
'flags'
:
'a'
});
handler
.
get
(
source
,
(
response
)
=>
{
...
...
@@ -47,23 +45,36 @@ export class NodeFileHandler implements FileHandler {
file
.
write
(
chunk
,
'binary'
);
if
((
prog
/
size
)
>
nextProg
)
{
subscriber
.
next
(
prog
/
size
);
this
.
emit
(
'progress'
,
prog
/
size
);
nextProg
+=
(
1
/
progCounts
);
}
});
response
.
on
(
'end'
,
()
=>
{
response
.
on
ce
(
'end'
,
()
=>
{
file
.
end
();
subscriber
.
complete
(
);
this
.
emit
(
'complete'
);
});
}).
on
(
'error'
,
(
error
)
=>
{
fs
.
unlink
(
target
);
subscriber
.
error
(
"Error while downloading: "
+
error
);
this
.
emit
(
"error"
,
"Error while downloading: "
+
error
);
});
return
this
;
}
}
cleanup
(
files
:
Array
<
File
>
,
basePath
?:
string
)
{
try
{
let
localFiles
=
fs
.
readdirSync
(
basePath
);
Util
.
getFilesForCleanup
(
files
,
localFiles
)
.
forEach
((
file
)
=>
{
fs
.
unlinkSync
(
basePath
+
"/"
+
file
);
});
}
catch
(
e
)
{
}
return
this
;
}
}
\ No newline at end of file
...
...
src/file-replicator.ts
View file @
6fb2e37
import
{
FileHandler
}
from
'./api/file-handler'
;
import
{
File
}
from
'./api/file'
;
import
{
Util
}
from
'./util'
;
import
{
EventEmitter
}
from
'events'
;
import
{
FileHandler
}
from
'./api/file-handler'
;
import
{
File
}
from
'./api/file'
;
import
{
Util
}
from
'./util'
;
import
{
EventEmitter
}
from
'events'
;
export
class
FileReplicator
extends
EventEmitter
{
...
...
@@ -9,46 +9,52 @@ export class FileReplicator extends EventEmitter {
super
();
}
protected
_files
:
Array
<
File
>
=
[];
protected
_files
:
Array
<
File
>
=
[];
protected
_itemValidator
:
(
item
:
any
)
=>
boolean
=
null
;
protected
_fileHandler
:
FileHandler
=
null
;
protected
_retryTimeout
:
number
=
0
;
protected
_itemValidator
:
(
item
:
any
)
=>
boolean
=
null
;
protected
_fileHandler
:
FileHandler
=
null
;
protected
_retryTimeout
:
number
=
100
;
protected
_retries
:
number
=
10
;
protected
_itemKey
=
"type"
;
protected
_itemValue
=
"asset"
;
protected
_itemSourceAttribute
=
"source"
;
protected
_itemTargetAttribute
=
"target"
;
protected
_targetDirectory
=
""
;
get
files
():
Array
<
File
>
{
return
this
.
_files
;
}
set
fileHandler
(
handler
:
FileHandler
)
{
set
fileHandler
(
handler
:
FileHandler
)
{
this
.
_fileHandler
=
handler
;
}
set
retryTimeout
(
timeout
:
number
)
{
get
fileHandler
()
:
FileHandler
{
return
this
.
_fileHandler
;
}
set
retryTimeout
(
timeout
:
number
)
{
this
.
_retryTimeout
=
timeout
;
}
set
itemValidator
(
validator
:
(
item
:
any
)
=>
boolean
)
{
set
itemValidator
(
validator
:
(
item
:
any
)
=>
boolean
)
{
this
.
_itemValidator
=
validator
;
}
set
itemKey
(
key
:
string
)
{
set
itemKey
(
key
:
string
)
{
this
.
_itemKey
=
key
;
}
set
itemValue
(
value
:
string
)
{
set
itemValue
(
value
:
string
)
{
this
.
_itemValue
=
value
;
}
set
itemSourceAttribute
(
sourceAttribute
:
string
)
{
set
itemSourceAttribute
(
sourceAttribute
:
string
)
{
this
.
_itemSourceAttribute
=
sourceAttribute
;
}
set
itemTargetAttribute
(
targetAttribute
:
string
)
{
set
itemTargetAttribute
(
targetAttribute
:
string
)
{
this
.
_itemTargetAttribute
=
targetAttribute
;
}
...
...
@@ -68,18 +74,26 @@ export class FileReplicator extends EventEmitter {
return
this
.
_itemTargetAttribute
;
}
init
(
files
:
Array
<
File
>
=
[])
{
set
targetDirectory
(
targetDirectory
:
string
)
{
this
.
_targetDirectory
=
targetDirectory
;
}
get
targetDirectory
()
{
return
this
.
_targetDirectory
;
}
clear
(
files
:
Array
<
File
>
=
[])
{
this
.
_files
=
files
;
}
/**
* change from pouchdb replicate
*/
pushChanges
(
change
:
any
)
{
let
items
:
Array
<
any
>
=
[];
pushChanges
(
docs
:
Array
<
any
>
)
{
let
items
:
Array
<
any
>
=
[];
if
(
change
&&
change
.
docs
&&
change
.
docs
.
length
>
0
)
{
for
(
let
item
of
change
.
docs
)
{
if
(
docs
&&
docs
.
length
>
0
)
{
for
(
let
item
of
docs
)
{
if
(
item
[
this
.
_itemKey
]
&&
item
[
this
.
_itemKey
]
===
this
.
_itemValue
)
{
items
.
push
(
item
);
}
...
...
@@ -93,35 +107,35 @@ export class FileReplicator extends EventEmitter {
}
}
downloadFiles
(
files
:
Array
<
File
>
,
fileHandler
:
FileHandler
,
index
:
number
=
0
)
{
downloadFiles
(
files
:
Array
<
File
>
,
fileHandler
:
FileHandler
,
index
:
number
=
0
)
{
if
(
index
>=
files
.
length
)
{
return
;
}
this
.
emit
(
'start'
,
{
progress
:
0
,
index
:
index
,
length
:
files
.
length
});
this
.
emit
(
'start'
,
{
progress
:
0
,
index
:
index
,
length
:
files
.
length
});
fileHandler
.
download
(
files
[
index
].
source
,
files
[
index
].
target
)
.
subscribe
(
progress
=>
{
this
.
emit
(
'progress'
,
{
progress
:
progress
,
index
:
index
,
length
:
files
.
length
})
}
,
error
=>
{
this
.
emit
(
'error'
,
{
progress
:
0
,
index
:
index
,
length
:
files
.
length
,
error
:
error
});
}
,
()
=>
{
this
.
emit
(
'complete'
,
{
progress
:
100
,
index
:
index
,
length
:
files
.
length
}
);
this
.
downloadFiles
(
files
,
fileHandler
,
index
+
1
);
}
);
}
prepareFiles
(
items
:
Array
<
any
>
)
:
Array
<
File
>
{
.
on
(
'progress'
,
(
progress
)
=>
{
this
.
emit
(
'file-progress'
,
{
progress
:
progress
,
index
:
index
,
length
:
files
.
length
})
})
.
once
(
'error'
,
error
=>
{
this
.
emit
(
'file-error'
,
{
progress
:
0
,
index
:
index
,
length
:
files
.
length
,
error
:
error
});
fileHandler
.
removeAllListeners
();
})
.
once
(
'complete'
,
()
=>
{
this
.
emit
(
'file-complete'
,
{
progress
:
100
,
index
:
index
,
length
:
files
.
length
});
fileHandler
.
removeAllListeners
(
);
this
.
downloadFiles
(
files
,
fileHandler
,
index
+
1
);
})
.
download
(
files
[
index
].
source
,
this
.
targetDirectory
+
files
[
index
].
target
);
}
prepareFiles
(
items
:
Array
<
any
>
):
Array
<
File
>
{
let
output
=
[];
for
(
let
item
of
items
)
{
if
(
item
[
this
.
_itemSourceAttribute
]
&&
(
!
this
.
_itemValidator
||
this
.
_itemValidator
(
item
)))
{
let
file
=
{
source
:
item
[
this
.
_itemSourceAttribute
]
,
target
:
''
};
let
file
=
{
source
:
item
[
this
.
_itemSourceAttribute
],
target
:
''
};
if
(
item
[
this
.
_itemTargetAttribute
])
{
file
.
target
=
item
[
this
.
_itemTargetAttribute
];
...
...
@@ -136,29 +150,47 @@ export class FileReplicator extends EventEmitter {
return
output
;
}
start
()
{
this
.
on
(
'complete'
,
(
event
:
any
)
=>
{
start
(
retries
:
number
=
10
)
{
this
.
_retries
=
retries
;
this
.
on
(
'file-complete'
,
(
event
:
any
)
=>
{
if
((
event
.
index
+
1
)
>=
event
.
length
)
{
this
.
replicationFinalized
(
event
.
index
);
}
});
this
.
on
(
'
error'
,
(
event
:
any
)
=>
{
this
.
on
(
'
file-error'
,
(
event
:
any
)
=>
{
this
.
replicationFinalized
(
event
.
index
);
});
if
(
this
.
_fileHandler
&&
this
.
_files
.
length
>
0
)
{
this
.
downloadFiles
(
this
.
_files
,
this
.
_fileHandler
);
}
else
{
this
.
emit
(
'complete'
);
}
}
cleanup
()
{
this
.
fileHandler
.
cleanup
(
this
.
_files
,
this
.
_targetDirectory
)
.
then
(()
=>
{
this
.
emit
(
'cleanup-complete'
);
}).
catch
(()
=>
{
this
.
emit
(
'cleanup-error'
);
});
}
replicationFinalized
(
lastIndex
:
number
)
{
if
(
lastIndex
+
1
>=
this
.
_files
.
length
)
{
// all finished
this
.
_files
=
[];
this
.
emit
(
'final'
);
}
else
if
(
this
.
_retryTimeout
>
0
)
{
// restart after last success
this
.
_files
.
splice
(
0
,
lastIndex
);
replicationFinalized
(
lastIndex
:
number
)
{
if
(
lastIndex
+
1
>=
this
.
_files
.
length
)
{
// all finished
this
.
emit
(
'complete'
);
}
else
if
(
this
.
_retries
>
0
)
{
// restart after last success
this
.
_files
.
splice
(
0
,
lastIndex
);
setTimeout
(()
=>
{
this
.
_retries
=-
1
;
this
.
downloadFiles
(
this
.
_files
,
this
.
_fileHandler
);
},
this
.
_retryTimeout
);
}
else
{
this
.
emit
(
'error'
);
}
}
...
...
src/node-main.ts
View file @
6fb2e37
...
...
@@ -2,17 +2,22 @@ import { NodeFileHandler } from './file-handler/node-file-handler';
export
default
class
Bsync
{
static
configIpcMain
(
ipcMain
:
any
,
downloadDir
:
string
)
{
let
nodeFileHander
=
new
NodeFileHandler
();
static
configIpcMain
(
ipcMain
:
any
,
basePath
:
string
)
{
ipcMain
.
on
(
'bsync-download'
,
(
event
,
args
)
=>
{
nodeFileHander
.
download
(
args
.
source
,
downloadDir
+
args
.
target
)
.
subscribe
(
(
progress
:
number
)
=>
{
event
.
sender
.
send
(
'bsync-download-progress'
,
progress
);
}
,
(
error
:
any
)
=>
{
event
.
sender
.
send
(
'bsync-download-error'
,
error
);
}
,
()
=>
{
event
.
sender
.
send
(
'bsync-download-complete'
);
}
);
let
nodeFileHander
=
new
NodeFileHandler
();
nodeFileHander
.
download
(
args
.
source
,
basePath
+
"/"
+
args
.
target
)
.
on
(
'progress'
,
(
progress
:
number
)
=>
{
event
.
sender
.
send
(
'bsync-download-progress'
,
progress
);
})
.
once
(
'error'
,
(
error
)
=>
{
nodeFileHander
.
removeAllListeners
();
event
.
sender
.
send
(
'bsync-download-error'
,
error
);
})
.
once
(
'complete'
,
()
=>
{
nodeFileHander
.
removeAllListeners
();
event
.
sender
.
send
(
'bsync-download-complete'
);
});
});
ipcMain
.
on
(
'bsync-cleanup'
,
(
event
,
args
)
=>
{
let
nodeFileHandler
=
new
NodeFileHandler
();
nodeFileHandler
.
cleanup
(
args
.
files
,
basePath
);
event
.
sender
.
send
(
'bsync-cleanup-complete'
);
});
}
}
\ No newline at end of file
...
...
src/service-locator.ts
View file @
6fb2e37
import
{
FileHandler
}
from
'./api/file-handler'
;
import
{
ElectronFileHandler
}
from
'./file-handler/electron-file-handler'
;
import
{
Cordova
Download
er
}
from
'./file-handler/cordova-file-handler'
;
import
{
Cordova
FileHandl
er
}
from
'./file-handler/cordova-file-handler'
;
import
{
FileReplicator
}
from
'./file-replicator'
;
import
{
Config
,
...
...
@@ -8,7 +8,8 @@ import {
CONFIG_ITEM_KEY
,
CONFIG_ITEM_VALUE
,
CONFIG_ITEM_TARGET_ATTRIBUTE
,
CONFIG_ITEM_SOURCE_ATTRIBUTE
CONFIG_ITEM_SOURCE_ATTRIBUTE
,
CONFIG_TARGET_DIRECTORY
}
from
'./config'
;
export
const
ENV_ELECTRON
=
"electron"
;
...
...
@@ -56,7 +57,7 @@ export class ServiceLocator {
}
if
(
environment
===
ENV_CORDOVA
)
{
return
new
Cordova
Download
er
();
return
new
Cordova
FileHandl
er
();
}
return
null
;
...
...
@@ -64,10 +65,9 @@ export class ServiceLocator {
static
getFileReplicator
()
:
FileReplicator
{
if
(
!
ServiceLocator
.
fileReplicator
)
{
ServiceLocator
.
fileReplicator
=
new
FileReplicator
();
ServiceLocator
.
fileReplicator
.
fileHandler
=
ServiceLocator
.
getFileHandler
();
}
if
(
ServiceLocator
.
getConfig
().
hasConfig
(
CONFIG_RETRY_TIMEOUT
))
{
ServiceLocator
.
fileReplicator
.
retryTimeout
=
ServiceLocator
.
getConfig
().
getConfig
(
CONFIG_RETRY_TIMEOUT
);
...
...
@@ -84,6 +84,8 @@ export class ServiceLocator {
if
(
ServiceLocator
.
getConfig
().
hasConfig
(
CONFIG_ITEM_TARGET_ATTRIBUTE
))
{
ServiceLocator
.
fileReplicator
.
itemTargetAttribute
=
ServiceLocator
.
getConfig
().
getConfig
(
CONFIG_ITEM_TARGET_ATTRIBUTE
);
}
if
(
ServiceLocator
.
getConfig
().
hasConfig
(
CONFIG_TARGET_DIRECTORY
))
{
ServiceLocator
.
fileReplicator
.
targetDirectory
=
ServiceLocator
.
getConfig
().
getConfig
(
CONFIG_TARGET_DIRECTORY
);
}
return
ServiceLocator
.
fileReplicator
;
...
...
src/util.ts
View file @
6fb2e37
import
{
File
}
from
'./api/file'
;
export
class
Util
{
static
getNameHash
(
path
:
string
)
{
...
...
@@ -7,4 +9,36 @@ export class Util {
return
"bsync_"
+
Math
.
abs
(
r
);
}
/**
* index >= 0, localFile is in files
* index < 0, localFile is not in files
*/
static
getFileIndex
(
files
:
Array
<
File
>
,
localFile
:
string
)
:
number
{
for
(
let
i
=
0
;
i
<
files
.
length
;
i
++
)
{
if
(
localFile
==
files
[
i
].
target
)
{
return
i
;
}
}
return
-
1
;
}
static
getFilesForCleanup
(
files
:
Array
<
File
>
,
localFiles
:
Array
<
string
>
)
:
Array
<
string
>
{
let
filesForCleanup
=
[];
for
(
let
localFile
of
localFiles
)
{
let
index
=
-
1
;
index
=
Util
.
getFileIndex
(
files
,
localFile
);
if
(
index
<
0
)
{
filesForCleanup
.
push
(
localFile
);
}
else
{
// splice for performance improvement only
files
.
splice
(
index
,
1
);
}
}
return
filesForCleanup
;
}
}
\ No newline at end of file
...
...
Please
register
or
login
to post a comment