Open alexspevak opened 1 year ago
designId
will be removed
So, it's nothing necessary? What did we use it for?
designId
will be removedSo, it's nothing necessary? What did we use it for?
We used it for designating design id if provided, instead of random, but this was only used in octopus-psd
We used it for designating design id if provided, instead of random, but this was only used in octopus-psd
That's obvious. But why for?
Another question is regarding fileMeta
. I'd name it designMeta
so we don't need to bring on new terminology (such as file
is). Also, I am not sure about type:
{
designName: string
content: {
topLevelArtboards: NamedArtboard[]
}
}
I think in Figma we provide not only top level artboards, but also components. Also, there's no NamedArtboard
type in your examples.
Update: I have found the section when you say that Figma has richer result type and that it's Figma specific. It's not Figma specific and it should be done in other converters too.
Regarding cleanup()
. I was thinking about it and actually I think that this shouldn't be generalized because many readers will not have nothing to clean up. Also, by standardizing the API we only define exact subset of possible API, but not the complete API because Readers should just implement our interface, but there's nothing wrong if Readers will extend this API. So, cleanup()
is just a case when we extend Reader and we don't have to use it necessary on every reader.
Regarding getSourceDesign()
. I think we should expect that in the future we will want to use more options, so instead of passing ids
as argument I'd rather use an object with named property ids
.
I think that getSourceDesign()
is better name for this method than parse()
because parse()
is too abstract.
Regarding images. I see that you suggested the following type:
{
id: string,
getImageData: () => Promise<Uint8Array>,
path?: string
}
I am not sure about that path
. Why do you think we need it? Also, I'd rename getImageData
to just getImage
.
Also, maybe you remember that in some Exporters which you used for testing you had to implement methods with the body like:
exportSomething() {
console.log('exporting something')
return Promise.resolve()
}
This should be handled by some abstract class which by default implements all the methods for exporters/readers and just use some simple dumb logic inside of such methods. For example:
class AbstractExporter {
exportSomething() {
console.warn('Exporing something (warning - default (not overriden) method is called!)')
return Promise.resolve(null)
}
}
class MyExporter extends AbstractExporter {
exportSomething() {
// ... some real logic
}
}
I am not sure what we should use here, actually - implements
or extends
. Because: implements
will force user to implement all the methods of exporter - I am not sure it's developer friendly. On the other hand it's more correct.
Also, maybe you remember that in some Exporters which you used for testing you had to implement methods with the body like:
exportSomething() { console.log('exporting something') return Promise.resolve() }
This should be handled by some abstract class which by default implements all the methods for exporters/readers and just use some simple dumb logic inside of such methods. For example:
class AbstractExporter { exportSomething() { console.warn('Exporing something (warning - default (not overriden) method is called!)') return Promise.resolve(null) } } class MyExporter extends AbstractExporter { exportSomething() { // ... some real logic } }
I am not sure what we should use here, actually -
implements
orextends
. Because:implements
will force user to implement all the methods of exporter - I am not sure it's developer friendly. On the other hand it's more correct.
you can force developer to create something by using abstract
keyword before the method
you can force developer to create something by using
abstract
keyword before the method
I know, but I am saying that I am not sure that forcing is a dev-friendly practice. Actually, I think implements
is better idea. Atleast user will implement all the required methods of exporter. 🤔
I am confused. Do we want to be dev-friendly or we want to force user to implement something? With abstract class we can achieve both things. With implements
we can only force them to implement required methods.
In this document, I will be describing the current status and future steps which we have been or will be regularly discussing with @cerosnikita on how to unify all octopus-3 interface.
At this moment readers are described and this will be one of my first steps.
READERS
Constructor Options
Node
Readers will have following options:
{path: string}
Notes
octopus-xd: currently it has following options
we will keep storeAssetsOnFs and will be storing assets on file system if such option is provided.
file
will be replaced withpath
octopus-fig has totaly different interface and it's constructor options will not be affected by this change
octopus-psd uses following options:
export type WithRendererOptions = { /* Path to the .psd design file. / path: string
/* Unique ID. If not passed, will be generated by UUIDv4 / designId?: string }
SourDesign
with selected artboardIds if such option is provided.Notes
but these extras are figma specific
parse
which returnsEventEmitter
but this is figma specific. octopus-figparse
method returns DesignEmitter and it also hasartboardIds
filter implemented. It is yet unclear for me if we will renamegetSourceDesign
toparse
or vice versa, or invent different name.Images
Image data should be read as
getImageData
function which returnsPromise<Uint8Array>
.Notes
BitmapReader
from pdfcpu which is very expensive and inNode
environment reads data from disk.Node
environment reads data if data is stored on disk (see section on Constructor option), if not it just keeps the interface as data are stored in runtime.Exporters
Images
We have decided that images will exported as type
{id:string, getImageData:()=>Promise<Uint8Array>, path?:string}
. User will have option to process images in exporter. This is specifically important for web version of octopus-ai where processing images is very expensive. At the moment all of the converters pass processed images to converters, some of them just have intermediate step.Notes
Differences in individual converters:
path
instead ofid
. It will need refactoring to useid
. Also, for some reason, it is using NodeBuffer
as way of storing images. This will also need further investigation.so exporting images as a function will be done to keep the same interface.
OCTOPUS-COMPONENT
I propose to use following interface:
GenericComponentConversionResult is type shared from
octopus-common
(already implemented in work in progress merge request). This method should be mandatory.Notes
octopus-psd
uses similar interface where role is missing. As this is optional parameter, this can be easily adjusted.octopus-xd
andoctopus-ai
useexportArtboard
where they exportOctopus['OctopusComponent']
but alsoSourceComponent
. SourceComponent should be exported in separate method.octopus-fig
is already using proposed interfaceMANIFEST
For exporting
Manifest['OctopusManifest']
I would propose following interface:GenericComponentConversionResult is type shared from
octopus-common
(already implemented in work in progress merge request). This method should be mandatory.Notes
octopus-fig
is plainly exportingManifest['OctopusManifest']
and it does not convert it with benchmark function, thereforeDesignConversionResult
is not appliable. We can convert withbenchmark
function inoctopus-fig
too and have same interface.signaling that last item has been sent for exporting
For this function
is implemented in all converters and needs no change. This method should be mandatory in proposed interface.
statistics
I propose following method:
This is only implemented in
octopus-psd
and should be implemented in all other exporters.statistics
param is optional as not always user will be collecting statistics. This method should be mandatory in proposed interface.path to target directory
We use following method in all converters except for
octopus-fig
:octopus-fig
is missing this method but can be easily implemented.WebExporter
can implement empty mock method.SourceArtboard
octopus-xd
andoctopus-ai
export itsSourceArtboard
in the same method they exportOctopus['OctopusComponent']
. This should be separated and new method should be optional in interface as it is used for dev purposes. I propose following interface:SourceDesign
only
octopus-xd
exports its Sourcedesign with following signatureI propose not to have interface.
octopus-xd
user can implement this without interface.SPECIFIC METHODS:
Following methods are specific individual converters, they can be left as they are and no interface is needed.
octopus-fig:
octopus-ai:
octopus-ai
uses :to export metaData about the
Adobe Illustrator
version and private text data.Naming:
I propose following names for exporters : WebExporter, LocalExporter and DebugExporter.